1
0
Fork 0

Squashed 'tmk_core/' changes from 7967731..b9e0ea0

b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk'
7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5

git-subtree-dir: tmk_core
git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
Jun Wako 2015-04-24 16:26:14 +09:00
parent a20ef7052c
commit 1fe4406f37
4198 changed files with 2016457 additions and 0 deletions

View file

@ -0,0 +1,36 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IUSBENUMERATOR_H_
#define IUSBENUMERATOR_H_
#include "stdint.h"
#include "USBEndpoint.h"
/*
Generic interface to implement for "smart" USB enumeration
*/
class IUSBEnumerator
{
public:
virtual void setVidPid(uint16_t vid, uint16_t pid) = 0;
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used
};
#endif /*IUSBENUMERATOR_H_*/

View file

@ -0,0 +1,329 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : devdrv_usb_host_api.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB_HOST_API_H
#define USB_HOST_API_H
#include "r_typedefs.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
#define USB_HOST_PORTNUM (2)
#define USB_HOST_ELT_INTERRUPT_LEVEL (9)
#define USBHCLOCK_X1_48MHZ (0x0000u) /* USB_X1_48MHz */
#define USBHCLOCK_EXTAL_12MHZ (0x0004u) /* EXTAL_12MHz */
#define USB_HOST_MAX_DEVICE (10)
#define USB_HOST_ON (1)
#define USB_HOST_OFF (0)
#define USB_HOST_YES (1)
#define USB_HOST_NO (0)
#define USB_HOST_NON_SPEED (0)
#define USB_HOST_LOW_SPEED (1)
#define USB_HOST_FULL_SPEED (2)
#define USB_HOST_HIGH_SPEED (3)
/* DEVDRV_SUCCESS(0) & DEVDRV_ERROR(-1) is dev_drv.h */
#define DEVDRV_USBH_STALL (-2)
#define DEVDRV_USBH_TIMEOUT (-3)
#define DEVDRV_USBH_NAK_TIMEOUT (-4)
#define DEVDRV_USBH_DETACH_ERR (-5)
#define DEVDRV_USBH_SETUP_ERR (-6)
#define DEVDRV_USBH_CTRL_COM_ERR (-7)
#define DEVDRV_USBH_COM_ERR (-8)
#define DEVDRV_USBH_DEV_ADDR_ERR (-9)
#define USB_HOST_ATTACH (1)
#define USB_HOST_DETACH (0)
#define USB_HOST_MAX_PIPE_NO (9u)
#define USB_HOST_PIPE0 (0)
#define USB_HOST_PIPE1 (1)
#define USB_HOST_PIPE2 (2)
#define USB_HOST_PIPE3 (3)
#define USB_HOST_PIPE4 (4)
#define USB_HOST_PIPE5 (5)
#define USB_HOST_PIPE6 (6)
#define USB_HOST_PIPE7 (7)
#define USB_HOST_PIPE8 (8)
#define USB_HOST_PIPE9 (9)
#define USB_HOST_ISO (0xc000u)
#define USB_HOST_INTERRUPT (0x8000u)
#define USB_HOST_BULK (0x4000u)
#define USB_HOST_PIPE_IDLE (0x00)
#define USB_HOST_PIPE_WAIT (0x01)
#define USB_HOST_PIPE_DONE (0x02)
#define USB_HOST_PIPE_NORES (0x03)
#define USB_HOST_PIPE_STALL (0x04)
#define USB_HOST_PIPE_ERROR (0x05)
#define USB_HOST_NONE (0x0000u)
#define USB_HOST_BFREFIELD (0x0400u)
#define USB_HOST_BFREON (0x0400u)
#define USB_HOST_BFREOFF (0x0000u)
#define USB_HOST_DBLBFIELD (0x0200u)
#define USB_HOST_DBLBON (0x0200u)
#define USB_HOST_DBLBOFF (0x0000u)
#define USB_HOST_CNTMDFIELD (0x0100u)
#define USB_HOST_CNTMDON (0x0100u)
#define USB_HOST_CNTMDOFF (0x0000u)
#define USB_HOST_SHTNAKON (0x0080u)
#define USB_HOST_SHTNAKOFF (0x0000u)
#define USB_HOST_DIRFIELD (0x0010u)
#define USB_HOST_DIR_H_OUT (0x0010u)
#define USB_HOST_DIR_H_IN (0x0000u)
#define USB_HOST_EPNUMFIELD (0x000fu)
#define USB_HOST_CUSE (0)
#define USB_HOST_D0USE (1)
#define USB_HOST_D0DMA (2)
#define USB_HOST_D1USE (3)
#define USB_HOST_D1DMA (4)
#define USB_HOST_CFIFO_USE (0x0000)
#define USB_HOST_D0FIFO_USE (0x1000)
#define USB_HOST_D1FIFO_USE (0x2000)
#define USB_HOST_D0FIFO_DMA (0x5000)
#define USB_HOST_D1FIFO_DMA (0x6000)
#define USB_HOST_BUF2FIFO (0)
#define USB_HOST_FIFO2BUF (1)
#define USB_HOST_DRV_DETACHED (0x0000)
#define USB_HOST_DRV_ATTACHED (0x0001)
#define USB_HOST_DRV_GET_DEVICE_DESC_64 (0x0002)
#define USB_HOST_DRV_POWERED (0x0003)
#define USB_HOST_DRV_DEFAULT (0x0004)
#define USB_HOST_DRV_SET_ADDRESS (0x0005)
#define USB_HOST_DRV_ADDRESSED (0x0006)
#define USB_HOST_DRV_GET_DEVICE_DESC_18 (0x0007)
#define USB_HOST_DRV_GET_CONGIG_DESC_9 (0x0008)
#define USB_HOST_DRV_GET_CONGIG_DESC (0x0009)
#define USB_HOST_DRV_SET_CONFIG (0x000a)
#define USB_HOST_DRV_CONFIGURED (0x000b)
#define USB_HOST_DRV_SUSPEND (0x1000)
#define USB_HOST_DRV_NORES (0x0100)
#define USB_HOST_DRV_STALL (0x0200)
#define USB_HOST_TESTMODE_FORCE (0x000du)
#define USB_HOST_TESTMODE_TESTPACKET (0x000cu)
#define USB_HOST_TESTMODE_SE0_NAK (0x000bu)
#define USB_HOST_TESTMODE_K (0x000au)
#define USB_HOST_TESTMODE_J (0x0009u)
#define USB_HOST_TESTMODE_NORMAL (0x0000u)
#define USB_HOST_DT_DEVICE (0x01)
#define USB_HOST_DT_CONFIGURATION (0x02)
#define USB_HOST_DT_STRING (0x03)
#define USB_HOST_DT_INTERFACE (0x04)
#define USB_HOST_DT_ENDPOINT (0x05)
#define USB_HOST_DT_DEVICE_QUALIFIER (0x06)
#define USB_HOST_DT_OTHER_SPEED_CONFIGURATION (0x07)
#define USB_HOST_DT_INTERFACE_POWER (0x08)
#define USB_HOST_IF_CLS_NOT (0x00)
#define USB_HOST_IF_CLS_AUDIO (0x01)
#define USB_HOST_IF_CLS_CDC_CTRL (0x02)
#define USB_HOST_IF_CLS_HID (0x03)
#define USB_HOST_IF_CLS_PHYSICAL (0x05)
#define USB_HOST_IF_CLS_IMAGE (0x06)
#define USB_HOST_IF_CLS_PRINTER (0x07)
#define USB_HOST_IF_CLS_MASS (0x08)
#define USB_HOST_IF_CLS_HUB (0x09)
#define USB_HOST_IF_CLS_CDC_DATA (0x0a)
#define USB_HOST_IF_CLS_CRAD (0x0b)
#define USB_HOST_IF_CLS_CONTENT (0x0d)
#define USB_HOST_IF_CLS_VIDEO (0x0e)
#define USB_HOST_IF_CLS_DIAG (0xdc)
#define USB_HOST_IF_CLS_WIRELESS (0xe0)
#define USB_HOST_IF_CLS_APL (0xfe)
#define USB_HOST_IF_CLS_VENDOR (0xff)
#define USB_HOST_IF_CLS_HELE (0xaa)
#define USB_HOST_EP_DIR_MASK (0x80)
#define USB_HOST_EP_OUT (0x00)
#define USB_HOST_EP_IN (0x80)
#define USB_HOST_EP_TYPE (0x03)
#define USB_HOST_EP_CNTRL (0x00)
#define USB_HOST_EP_ISO (0x01)
#define USB_HOST_EP_BULK (0x02)
#define USB_HOST_EP_INT (0x03)
#define USB_HOST_EP_NUM_MASK (0x0f)
#define USB_HOST_PIPE_IN (0)
#define USB_HOST_PIPE_OUT (1)
#define USB_END_POINT_ERROR (0xffff)
#define USB_HOST_REQ_GET_STATUS (0x0000)
#define USB_HOST_REQ_CLEAR_FEATURE (0x0100)
#define USB_HOST_REQ_RESERVED2 (0x0200)
#define USB_HOST_REQ_SET_FEATURE (0x0300)
#define USB_HOST_REQ_RESERVED4 (0x0400)
#define USB_HOST_REQ_SET_ADDRESS (0x0500)
#define USB_HOST_REQ_GET_DESCRIPTOR (0x0600)
#define USB_HOST_REQ_SET_DESCRIPTOR (0x0700)
#define USB_HOST_REQ_GET_CONFIGURATION (0x0800)
#define USB_HOST_REQ_SET_CONFIGURATION (0x0900)
#define USB_HOST_REQ_GET_INTERFACE (0x0a00)
#define USB_HOST_REQ_SET_INTERFACE (0x0b00)
#define USB_HOST_REQ_SYNCH_FRAME (0x0c00)
#define USB_HOST_REQTYPE_HOST_TO_DEVICE (0x0000)
#define USB_HOST_REQTYPE_DEVICE_TO_HOST (0x0080)
#define USB_HOST_REQTYPE_STANDARD (0x0020)
#define USB_HOST_REQTYPE_CLASS (0x0040)
#define USB_HOST_REQTYPE_VENDOR (0x0060)
#define USB_HOST_REQTYPE_DEVICE (0x0000)
#define USB_HOST_REQTYPE_INTERFACE (0x0001)
#define USB_HOST_REQTYPE_ENDPOINT (0x0002)
#define USB_HOST_REQTYPE_OTHER (0x0003)
#define USB_HOST_DESCTYPE_DEVICE (0x0100)
#define USB_HOST_DESCTYPE_CONFIGURATION (0x0200)
#define USB_HOST_DESCTYPE_STRING (0x0300)
#define USB_HOST_DESCTYPE_INTERFACE (0x0400)
#define USB_HOST_DESCTYPE_ENDPOINT (0x0500)
#define USB_HOST_DESCTYPE_DEVICE_QUALIFIER (0x0600)
#define USB_HOST_DESCTYPE_OTHER_SPEED_CONFIGURATION (0x0700)
#define USB_HOST_DESCTYPE_INTERFACE_POWER (0x0800)
/*******************************************************************************
Variable Externs
*******************************************************************************/
typedef struct
{
uint16_t pipe_number;
uint16_t pipe_cfg;
uint16_t pipe_buf;
uint16_t pipe_max_pktsize;
uint16_t pipe_cycle;
uint16_t fifo_port;
} USB_HOST_CFG_PIPETBL_t;
typedef struct
{
uint32_t fifo;
uint32_t buffer;
uint32_t bytes;
uint32_t dir;
uint32_t size;
} USB_HOST_DMA_t;
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
uint16_t R_USB_api_host_init(uint16_t root, uint8_t int_level, uint16_t mode, uint16_t clockmode);
int32_t R_USB_api_host_enumeration(uint16_t root, uint16_t devadr);
int32_t R_USB_api_host_detach(uint16_t root);
int32_t R_USB_api_host_data_in(uint16_t root, uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t *data_buf);
int32_t R_USB_api_host_data_in2(uint16_t root, uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t *data_buf, uint32_t *bytes);
int32_t R_USB_api_host_data_out(uint16_t root, uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t *data_buf);
int32_t R_USB_api_host_control_transfer(uint16_t root, uint16_t devadr, uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len, uint8_t *Buf);
int32_t R_USB_api_host_set_endpoint(uint16_t root, uint16_t devadr, USB_HOST_CFG_PIPETBL_t *user_table, uint8_t *configdescriptor);
int32_t R_USB_api_host_clear_endpoint(uint16_t root, USB_HOST_CFG_PIPETBL_t *user_table);
int32_t R_USB_api_host_clear_endpoint_pipe(uint16_t root, uint16_t pipe_sel, USB_HOST_CFG_PIPETBL_t *user_table);
uint16_t R_USB_api_host_SetEndpointTable(uint16_t root, uint16_t devadr, USB_HOST_CFG_PIPETBL_t *user_table, uint8_t* Table);
int32_t R_USB_api_host_GetDeviceDescriptor(uint16_t root, uint16_t devadr, uint16_t size, uint8_t *buf);
int32_t R_USB_api_host_GetConfigDescriptor(uint16_t root, uint16_t devadr, uint16_t size, uint8_t *buf);
int32_t R_USB_api_host_SetConfig(uint16_t root, uint16_t devadr, uint16_t confignum);
int32_t R_USB_api_host_SetInterface(uint16_t root, uint16_t devadr, uint16_t interface_alt, uint16_t interface_index);
int32_t R_USB_api_host_ClearStall(uint16_t root, uint16_t devadr, uint16_t ep_dir);
uint16_t R_USB_api_host_GetUsbDeviceState(uint16_t root);
void R_USB_api_host_elt_clocksel(uint16_t clockmode);
void R_USB_api_host_elt_4_4(uint16_t root);
void R_USB_api_host_elt_4_5(uint16_t root);
void R_USB_api_host_elt_4_6(uint16_t root);
void R_USB_api_host_elt_4_7(uint16_t root);
void R_USB_api_host_elt_4_8(uint16_t root);
void R_USB_api_host_elt_4_9(uint16_t root);
void R_USB_api_host_elt_get_desc(uint16_t root);
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host_api.h"
#include "usb1_host_api.h"
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
#ifdef USB0_HOST_API_H
uint16_t Userdef_USB_usb0_host_d0fifo_dmaintid(void);
uint16_t Userdef_USB_usb0_host_d1fifo_dmaintid(void);
void Userdef_USB_usb0_host_attach(void);
void Userdef_USB_usb0_host_detach(void);
void Userdef_USB_usb0_host_delay_1ms(void);
void Userdef_USB_usb0_host_delay_xms(uint32_t msec);
void Userdef_USB_usb0_host_delay_10us(uint32_t usec);
void Userdef_USB_usb0_host_delay_500ns(void);
void Userdef_USB_usb0_host_start_dma(USB_HOST_DMA_t * dma, uint16_t dfacc);
uint32_t Userdef_USB_usb0_host_stop_dma0(void);
uint32_t Userdef_USB_usb0_host_stop_dma1(void);
void Userdef_USB_usb0_host_notice(const char * format);
void Userdef_USB_usb0_host_user_rdy(const char * format, uint16_t data);
#endif
#ifdef USB1_HOST_API_H
uint16_t Userdef_USB_usb1_host_d0fifo_dmaintid(void);
uint16_t Userdef_USB_usb1_host_d1fifo_dmaintid(void);
void Userdef_USB_usb1_host_attach(void);
void Userdef_USB_usb1_host_detach(void);
void Userdef_USB_usb1_host_delay_1ms(void);
void Userdef_USB_usb1_host_delay_xms(uint32_t msec);
void Userdef_USB_usb1_host_delay_10us(uint32_t usec);
void Userdef_USB_usb1_host_delay_500ns(void);
void Userdef_USB_usb1_host_start_dma(USB_HOST_DMA_t * dma, uint16_t dfacc);
uint32_t Userdef_USB_usb1_host_stop_dma0(void);
uint32_t Userdef_USB_usb1_host_stop_dma1(void);
void Userdef_USB_usb1_host_notice(const char * format);
void Userdef_USB_usb1_host_user_rdy(const char * format, uint16_t data);
#endif
#endif /* USB_HOST_API_H */
/* End of File */

View file

@ -0,0 +1,201 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb_host.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB_HOST_H
#define USB_HOST_H
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "r_typedefs.h"
#include "iodefine.h"
#include "rza_io_regrw.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
#define USB_HOST_DEVICE_0 (0u)
#define USB_HOST_DEVICE_1 (1u)
#define USB_HOST_DEVICE_2 (2u)
#define USB_HOST_DEVICE_3 (3u)
#define USB_HOST_DEVICE_4 (4u)
#define USB_HOST_DEVICE_5 (5u)
#define USB_HOST_DEVICE_6 (6u)
#define USB_HOST_DEVICE_7 (7u)
#define USB_HOST_DEVICE_8 (8u)
#define USB_HOST_DEVICE_9 (9u)
#define USB_HOST_DEVICE_10 (10u)
#define USB_HOST_ENDPOINT_DESC (0x05)
#define USB_HOST_BITUPLLE (0x0002u)
#define USB_HOST_BITUCKSEL (0x0004u)
#define USB_HOST_BITBWAIT (0x003fu)
#define USB_HOST_BUSWAIT_02 (0x0000u)
#define USB_HOST_BUSWAIT_03 (0x0001u)
#define USB_HOST_BUSWAIT_04 (0x0002u)
#define USB_HOST_BUSWAIT_05 (0x0003u)
#define USB_HOST_BUSWAIT_06 (0x0004u)
#define USB_HOST_BUSWAIT_07 (0x0005u)
#define USB_HOST_BUSWAIT_08 (0x0006u)
#define USB_HOST_BUSWAIT_09 (0x0007u)
#define USB_HOST_BUSWAIT_10 (0x0008u)
#define USB_HOST_BUSWAIT_11 (0x0009u)
#define USB_HOST_BUSWAIT_12 (0x000au)
#define USB_HOST_BUSWAIT_13 (0x000bu)
#define USB_HOST_BUSWAIT_14 (0x000cu)
#define USB_HOST_BUSWAIT_15 (0x000du)
#define USB_HOST_BUSWAIT_16 (0x000eu)
#define USB_HOST_BUSWAIT_17 (0x000fu)
#define USB_HOST_FS_JSTS (0x0001u)
#define USB_HOST_LS_JSTS (0x0002u)
#define USB_HOST_BITRST (0x0040u)
#define USB_HOST_BITRESUME (0x0020u)
#define USB_HOST_BITUACT (0x0010u)
#define USB_HOST_HSPROC (0x0004u)
#define USB_HOST_HSMODE (0x0003u)
#define USB_HOST_FSMODE (0x0002u)
#define USB_HOST_LSMODE (0x0001u)
#define USB_HOST_UNDECID (0x0000u)
#define USB_HOST_BITRCNT (0x8000u)
#define USB_HOST_BITDREQE (0x1000u)
#define USB_HOST_BITMBW (0x0c00u)
#define USB_HOST_BITMBW_8 (0x0000u)
#define USB_HOST_BITMBW_16 (0x0400u)
#define USB_HOST_BITMBW_32 (0x0800u)
#define USB_HOST_BITBYTE_LITTLE (0x0000u)
#define USB_HOST_BITBYTE_BIG (0x0100u)
#define USB_HOST_BITISEL (0x0020u)
#define USB_HOST_BITCURPIPE (0x000fu)
#define USB_HOST_CFIFO_READ (0x0000u)
#define USB_HOST_CFIFO_WRITE (0x0020u)
#define USB_HOST_BITBVAL (0x8000u)
#define USB_HOST_BITBCLR (0x4000u)
#define USB_HOST_BITFRDY (0x2000u)
#define USB_HOST_BITDTLN (0x0fffu)
#define USB_HOST_BITBEMPE (0x0400u)
#define USB_HOST_BITNRDYE (0x0200u)
#define USB_HOST_BITBRDYE (0x0100u)
#define USB_HOST_BITBEMP (0x0400u)
#define USB_HOST_BITNRDY (0x0200u)
#define USB_HOST_BITBRDY (0x0100u)
#define USB_HOST_BITBCHGE (0x4000u)
#define USB_HOST_BITDTCHE (0x1000u)
#define USB_HOST_BITATTCHE (0x0800u)
#define USB_HOST_BITEOFERRE (0x0040u)
#define USB_HOST_BITBCHG (0x4000u)
#define USB_HOST_BITDTCH (0x1000u)
#define USB_HOST_BITATTCH (0x0800u)
#define USB_HOST_BITEOFERR (0x0040u)
#define USB_HOST_BITSIGNE (0x0020u)
#define USB_HOST_BITSACKE (0x0010u)
#define USB_HOST_BITSIGN (0x0020u)
#define USB_HOST_BITSACK (0x0010u)
#define USB_HOST_BITSUREQ (0x4000u)
#define USB_HOST_BITSQSET (0x0080u)
#define USB_HOST_PID_STALL2 (0x0003u)
#define USB_HOST_PID_STALL (0x0002u)
#define USB_HOST_PID_BUF (0x0001u)
#define USB_HOST_PID_NAK (0x0000u)
#define USB_HOST_PIPExBUF (64u)
#define USB_HOST_D0FIFO (0)
#define USB_HOST_D1FIFO (1)
#define USB_HOST_DMA_READY (0)
#define USB_HOST_DMA_BUSY (1)
#define USB_HOST_DMA_BUSYEND (2)
#define USB_HOST_FIFO_USE (0x7000)
#define USB_HOST_FIFOERROR (0xffff)
#define USB_HOST_WRITEEND (0)
#define USB_HOST_WRITESHRT (1)
#define USB_HOST_WRITING (2)
#define USB_HOST_WRITEDMA (3)
#define USB_HOST_READEND (0)
#define USB_HOST_READSHRT (1)
#define USB_HOST_READING (2)
#define USB_HOST_READOVER (3)
#define USB_HOST_READZERO (4)
#define USB_HOST_CMD_IDLE (0x0000)
#define USB_HOST_CMD_DOING (0x0001)
#define USB_HOST_CMD_DONE (0x0002)
#define USB_HOST_CMD_NORES (0x0003)
#define USB_HOST_CMD_STALL (0x0004)
#define USB_HOST_CMD_FIELD (0x000f)
#if 0
#define USB_HOST_CHG_CMDFIELD( r, v ) do { r &= ( ~USB_HOST_CMD_FIELD ); \
r |= v; } while(0)
#endif
#define USB_HOST_MODE_WRITE (0x0100)
#define USB_HOST_MODE_READ (0x0200)
#define USB_HOST_MODE_NO_DATA (0x0300)
#define USB_HOST_MODE_FIELD (0x0f00)
#define USB_HOST_STAGE_SETUP (0x0010)
#define USB_HOST_STAGE_DATA (0x0020)
#define USB_HOST_STAGE_STATUS (0x0030)
#define USB_HOST_STAGE_FIELD (0x00f0)
#if 0
#define USB_HOST_CHG_STAGEFIELD( r, v ) do { r &= ( ~USB_HOST_STAGE_FIELD ); \
r |= v; } while(0)
#endif
#define USB_HOST_DEVADD_MASK (0x7fc0)
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
extern uint16_t g_usb_host_elt_clockmode;
#endif /* USB_HOST_H */
/* End of File */

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb_host_version.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#define USB_HOST_LOCAL_Rev "VER080_140709"
/* End of File */

View file

@ -0,0 +1,60 @@
/* 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.
*/
#ifndef OHCI_WRAPP_RZ_A1_H
#define OHCI_WRAPP_RZ_A1_H
#ifdef __cplusplus
extern "C" {
#endif
#define OHCI_REG_REVISION (0x00) /* HcRevision */
#define OHCI_REG_CONTROL (0x04) /* HcControl */
#define OHCI_REG_COMMANDSTATUS (0x08) /* HcCommandStatus */
#define OHCI_REG_INTERRUPTSTATUS (0x0C) /* HcInterruptStatus */
#define OHCI_REG_INTERRUPTENABLE (0x10) /* HcInterruptEnable */
#define OHCI_REG_INTERRUPTDISABLE (0x14) /* HcInterruptDisable */
#define OHCI_REG_HCCA (0x18) /* HcHCCA */
#define OHCI_REG_PERIODCURRENTED (0x1C) /* HcPeriodCurrentED */
#define OHCI_REG_CONTROLHEADED (0x20) /* HcControlHeadED */
#define OHCI_REG_CONTROLCURRENTED (0x24) /* HcControlCurrentED */
#define OHCI_REG_BULKHEADED (0x28) /* HcBulkHeadED */
#define OHCI_REG_BULKCURRENTED (0x2C) /* HcBulkCurrentED */
#define OHCI_REG_DONEHEADED (0x30) /* HcDoneHead */
#define OHCI_REG_FMINTERVAL (0x34) /* HcFmInterval */
#define OHCI_REG_FMREMAINING (0x38) /* HcFmRemaining */
#define OHCI_REG_FMNUMBER (0x3C) /* HcFmNumber */
#define OHCI_REG_PERIODICSTART (0x40) /* HcPeriodicStart */
#define OHCI_REG_LSTHRESHOLD (0x44) /* HcLSThreshold */
#define OHCI_REG_RHDESCRIPTORA (0x48) /* HcRhDescriptorA */
#define OHCI_REG_RHDESCRIPTORB (0x4C) /* HcRhDescriptorB */
#define OHCI_REG_RHSTATUS (0x50) /* HcRhStatus */
#define OHCI_REG_RHPORTSTATUS1 (0x54) /* HcRhPortStatus1 */
typedef void (usbisr_fnc_t)(void);
extern void ohciwrapp_init(usbisr_fnc_t *p_usbisr_fnc);
extern uint32_t ohciwrapp_reg_r(uint32_t reg_ofs);
extern void ohciwrapp_reg_w(uint32_t reg_ofs, uint32_t set_data);
extern void ohciwrapp_interrupt(uint32_t int_sense);
#ifdef __cplusplus
}
#endif
#endif /* OHCI_WRAPP_RZ_A1_H */

View file

@ -0,0 +1,49 @@
/* 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.
*/
#ifndef OHCI_WRAPP_RZ_A1_LOCAL_H
#define OHCI_WRAPP_RZ_A1_LOCAL_H
#ifdef __cplusplus
extern "C" {
#endif
/* ConditionCode */
#define TD_CC_NOERROR (0)
#define TD_CC_CRC (1)
#define TD_CC_BITSTUFFING (2)
#define TD_CC_DATATOGGLEMISMATCH (3)
#define TD_CC_STALL (4)
#define TD_CC_DEVICENOTRESPONDING (5)
#define TD_CC_PIDCHECKFAILURE (6)
#define TD_CC_UNEXPECTEDPID (7)
#define TD_CC_DATAOVERRUN (8)
#define TD_CC_DATAUNDERRUN (9)
#define TD_CC_BUFFEROVERRUN (12)
#define TD_CC_BUFFERUNDERRUN (13)
#define TD_CC_NOT_ACCESSED_1 (14)
#define TD_CC_NOT_ACCESSED_2 (15)
extern void ohciwrapp_loc_Connect(uint32_t type);
extern void ohciwrapp_loc_TransEnd(uint32_t pipe, uint32_t ConditionCode);
#ifdef __cplusplus
}
#endif
#endif /* OHCI_WRAPP_RZ_A1_LOCAL_H */

View file

@ -0,0 +1,190 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "devdrv_usb_host_api.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/********************************************************************************************************/
/* Endpoint Configuration Data Format */
/********************************************************************************************************/
/* LINE1: Pipe Window Select Register */
/* CPU Access PIPE : PIPE1 to PIPE9 [ ### SET ### ] */
/* LINE2: Pipe Configuration Register */
/* Transfer Type : USB_HOST_NONE [ USB_HOST_NONE ] */
/* Buffer Ready interrupt : USB_HOST_NONE [ USB_HOST_NONE ] */
/* Double Buffer Mode : USB_HOST_CNT_ON / USB_HOST_CNT_OFF [ ### SET ### ] */
/* Continuous Transmit: : USB_HOST_CNT_ON / USB_HOST_CNT_OFF [ ### SET ### ] */
/* Short NAK : USB_HOST_NONE [ USB_HOST_NONE ] */
/* Transfer Direction : USB_HOST_NONE [ USB_HOST_NONE ] */
/* Endpoint Number : USB_HOST_NONE [ USB_HOST_NONE ] */
/* LINE3: Pipe Buffer Configuration Register */
/* Buffer Size : (uint16_t)((uint16_t)(((x) / 64) - 1) << 10) */
/* [ ### SET ### ] */
/* Buffer Top Number : (uint16_t)(x) [ ### SET ### ] */
/* LINE4: Pipe Maxpacket Size Register */
/* Max Packet Size : USB_HOST_NONE [ USB_HOST_NONE ] */
/* LINE5: Pipe Cycle Configuration Register (0x6C) */
/* ISO Buffer Flush Mode : USB_HOST_NONE [ USB_HOST_NONE ] */
/* ISO Interval Value : USB_HOST_NONE [ USB_HOST_NONE ] */
/* LINE6: use FIFO port */
/* : USB_HOST_CUSE [ ### SET ### ] */
/* : USB_HOST_D0USE / USB_HOST_D1USE */
/* : USB_HOST_D0DMA / USB_HOST_D0DMA */
/* LINE7: use FIFO port Endian : USB_HOST_FIFO_BIG / USB_HOST_FIFO_LITTLE [ #SET# ] */
/********************************************************************************************************/
/* Device Address 1 */
USB_HOST_CFG_PIPETBL_t usb_host_blk_ep_tbl1[ ] =
{
{
USB_HOST_PIPE3,
/* TYPE / BFRE / DBLB / CNTMD / SHTNAK / DIR / EPNUM */
USB_HOST_NONE | USB_HOST_NONE | USB_HOST_DBLBON | USB_HOST_CNTMDON | USB_HOST_NONE | USB_HOST_NONE | USB_HOST_NONE,
(uint16_t)((uint16_t)(((1024) / 64) - 1) << 10) | (uint16_t)(8),
USB_HOST_NONE,
USB_HOST_NONE,
USB_HOST_D0USE
},
{
/* Pipe end */
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF
}
};
USB_HOST_CFG_PIPETBL_t usb_host_int_ep_tbl1[ ] =
{
{
USB_HOST_PIPE6,
/* TYPE / BFRE / DBLB / CNTMD / SHTNAK / DIR / EPNUM */
USB_HOST_NONE | USB_HOST_NONE | USB_HOST_DBLBON | USB_HOST_CNTMDON | USB_HOST_NONE | USB_HOST_NONE | USB_HOST_NONE,
(uint16_t)((uint16_t)(((64) / 64) - 1) << 10) | (uint16_t)(40),
USB_HOST_NONE,
USB_HOST_NONE,
USB_HOST_D1USE
},
{
USB_HOST_PIPE7,
/* TYPE / BFRE / DBLB / CNTMD / SHTNAK / DIR / EPNUM */
USB_HOST_NONE | USB_HOST_NONE | USB_HOST_DBLBON | USB_HOST_CNTMDON | USB_HOST_NONE | USB_HOST_NONE | USB_HOST_NONE,
(uint16_t)((uint16_t)(((64) / 64) - 1) << 10) | (uint16_t)(41),
USB_HOST_NONE,
USB_HOST_NONE,
USB_HOST_D1USE
},
{
USB_HOST_PIPE8,
/* TYPE / BFRE / DBLB / CNTMD / SHTNAK / DIR / EPNUM */
USB_HOST_NONE | USB_HOST_NONE | USB_HOST_DBLBON | USB_HOST_CNTMDON | USB_HOST_NONE | USB_HOST_NONE | USB_HOST_NONE,
(uint16_t)((uint16_t)(((64) / 64) - 1) << 10) | (uint16_t)(42),
USB_HOST_NONE,
USB_HOST_NONE,
USB_HOST_D1USE
},
{
USB_HOST_PIPE9,
/* TYPE / BFRE / DBLB / CNTMD / SHTNAK / DIR / EPNUM */
USB_HOST_NONE | USB_HOST_NONE | USB_HOST_DBLBON | USB_HOST_CNTMDON | USB_HOST_NONE | USB_HOST_NONE | USB_HOST_NONE,
(uint16_t)((uint16_t)(((64) / 64) - 1) << 10) | (uint16_t)(43),
USB_HOST_NONE,
USB_HOST_NONE,
USB_HOST_D1USE
},
{
/* Pipe end */
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF
}
};
USB_HOST_CFG_PIPETBL_t usb_host_iso_ep_tbl1[ ] =
{
{
USB_HOST_PIPE1,
/* TYPE / BFRE / DBLB / CNTMD / SHTNAK / DIR / EPNUM */
USB_HOST_NONE | USB_HOST_NONE | USB_HOST_DBLBON | USB_HOST_CNTMDON | USB_HOST_NONE | USB_HOST_NONE | USB_HOST_NONE,
(uint16_t)((uint16_t)(((1024) / 64) - 1) << 10) | (uint16_t)(44),
USB_HOST_NONE,
USB_HOST_NONE,
USB_HOST_D1USE
},
{
USB_HOST_PIPE2,
/* TYPE / BFRE / DBLB / CNTMD / SHTNAK / DIR / EPNUM */
USB_HOST_NONE | USB_HOST_NONE | USB_HOST_DBLBON | USB_HOST_CNTMDON | USB_HOST_NONE | USB_HOST_NONE | USB_HOST_NONE,
(uint16_t)((uint16_t)(((1024) / 64) - 1) << 10) | (uint16_t)(60),
USB_HOST_NONE,
USB_HOST_NONE,
USB_HOST_D1USE
},
{
/* Pipe end */
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF,
0xFFFF
}
};
/* End of File */

View file

@ -0,0 +1,156 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB0_HOST_H
#define USB0_HOST_H
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "devdrv_usb_host_api.h"
#include "usb_host.h"
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
extern const uint16_t g_usb0_host_bit_set[];
extern uint32_t g_usb0_host_data_count[USB_HOST_MAX_PIPE_NO + 1];
extern uint8_t *g_usb0_host_data_pointer[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb0_host_PipeIgnore[];
extern uint16_t g_usb0_host_PipeTbl[];
extern uint16_t g_usb0_host_pipe_status[];
extern uint32_t g_usb0_host_PipeDataSize[];
extern USB_HOST_DMA_t g_usb0_host_DmaInfo[];
extern uint16_t g_usb0_host_DmaPipe[];
extern uint16_t g_usb0_host_DmaBval[];
extern uint16_t g_usb0_host_DmaStatus[];
extern uint16_t g_usb0_host_driver_state;
extern uint16_t g_usb0_host_ConfigNum;
extern uint16_t g_usb0_host_CmdStage;
extern uint16_t g_usb0_host_bchg_flag;
extern uint16_t g_usb0_host_detach_flag;
extern uint16_t g_usb0_host_attach_flag;
extern uint16_t g_usb0_host_UsbAddress;
extern uint16_t g_usb0_host_setUsbAddress;
extern uint16_t g_usb0_host_default_max_packet[USB_HOST_MAX_DEVICE + 1];
extern uint16_t g_usb0_host_UsbDeviceSpeed;
extern uint16_t g_usb0_host_SupportUsbDeviceSpeed;
extern uint16_t g_usb0_host_SavReq;
extern uint16_t g_usb0_host_SavVal;
extern uint16_t g_usb0_host_SavIndx;
extern uint16_t g_usb0_host_SavLen;
extern uint16_t g_usb0_host_pipecfg[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb0_host_pipebuf[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb0_host_pipemaxp[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb0_host_pipeperi[USB_HOST_MAX_PIPE_NO + 1];
/*******************************************************************************
Functions Prototypes
*******************************************************************************/
/* ==== common ==== */
void usb0_host_dma_stop_d0(uint16_t pipe, uint32_t remain);
void usb0_host_dma_stop_d1(uint16_t pipe, uint32_t remain);
uint16_t usb0_host_is_hispeed(void);
uint16_t usb0_host_is_hispeed_enable(void);
uint16_t usb0_host_start_send_transfer(uint16_t pipe, uint32_t size, uint8_t *data);
uint16_t usb0_host_write_buffer(uint16_t pipe);
uint16_t usb0_host_write_buffer_c(uint16_t pipe);
uint16_t usb0_host_write_buffer_d0(uint16_t pipe);
uint16_t usb0_host_write_buffer_d1(uint16_t pipe);
void usb0_host_start_receive_transfer(uint16_t pipe, uint32_t size, uint8_t *data);
uint16_t usb0_host_read_buffer(uint16_t pipe);
uint16_t usb0_host_read_buffer_c(uint16_t pipe);
uint16_t usb0_host_read_buffer_d0(uint16_t pipe);
uint16_t usb0_host_read_buffer_d1(uint16_t pipe);
uint16_t usb0_host_change_fifo_port(uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw);
void usb0_host_set_curpipe(uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw);
void usb0_host_set_curpipe2(uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw, uint16_t dfacc);
uint16_t usb0_host_get_mbw(uint32_t trncount, uint32_t dtptr);
uint16_t usb0_host_read_dma(uint16_t pipe);
void usb0_host_stop_transfer(uint16_t pipe);
void usb0_host_brdy_int(uint16_t status, uint16_t int_enb);
void usb0_host_nrdy_int(uint16_t status, uint16_t int_enb);
void usb0_host_bemp_int(uint16_t status, uint16_t int_enb);
void usb0_host_setting_interrupt(uint8_t level);
void usb0_host_reset_module(uint16_t clockmode);
uint16_t usb0_host_get_buf_size(uint16_t pipe);
uint16_t usb0_host_get_mxps(uint16_t pipe);
void usb0_host_enable_brdy_int(uint16_t pipe);
void usb0_host_disable_brdy_int(uint16_t pipe);
void usb0_host_clear_brdy_sts(uint16_t pipe);
void usb0_host_enable_bemp_int(uint16_t pipe);
void usb0_host_disable_bemp_int(uint16_t pipe);
void usb0_host_clear_bemp_sts(uint16_t pipe);
void usb0_host_enable_nrdy_int(uint16_t pipe);
void usb0_host_disable_nrdy_int(uint16_t pipe);
void usb0_host_clear_nrdy_sts(uint16_t pipe);
void usb0_host_set_pid_buf(uint16_t pipe);
void usb0_host_set_pid_nak(uint16_t pipe);
void usb0_host_set_pid_stall(uint16_t pipe);
void usb0_host_clear_pid_stall(uint16_t pipe);
uint16_t usb0_host_get_pid(uint16_t pipe);
void usb0_host_set_sqclr(uint16_t pipe);
void usb0_host_set_sqset(uint16_t pipe);
void usb0_host_set_csclr(uint16_t pipe);
void usb0_host_aclrm(uint16_t pipe);
void usb0_host_set_aclrm(uint16_t pipe);
void usb0_host_clr_aclrm(uint16_t pipe);
uint16_t usb0_host_get_sqmon(uint16_t pipe);
uint16_t usb0_host_get_inbuf(uint16_t pipe);
/* ==== host ==== */
void usb0_host_init_pipe_status(void);
int32_t usb0_host_CtrlTransStart(uint16_t devadr, uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len, uint8_t *Buf);
void usb0_host_SetupStage(uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len);
void usb0_host_CtrlReadStart(uint32_t Bsize, uint8_t *Table);
uint16_t usb0_host_CtrlWriteStart(uint32_t Bsize, uint8_t *Table);
void usb0_host_StatusStage(void);
void usb0_host_get_devadd(uint16_t addr, uint16_t *devadd);
void usb0_host_set_devadd(uint16_t addr, uint16_t *devadd);
void usb0_host_InitModule(void);
uint16_t usb0_host_CheckAttach(void);
void usb0_host_UsbDetach(void);
void usb0_host_UsbDetach2(void);
void usb0_host_UsbAttach(void);
uint16_t usb0_host_UsbBusReset(void);
int32_t usb0_host_UsbResume(void);
int32_t usb0_host_UsbSuspend(void);
void usb0_host_Enable_DetachINT(void);
void usb0_host_Disable_DetachINT(void);
void usb0_host_UsbStateManager(void);
#endif /* USB0_HOST_H */
/* End of File */

View file

@ -0,0 +1,112 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_api.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB0_HOST_API_H
#define USB0_HOST_API_H
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Variable Externs
*******************************************************************************/
/*******************************************************************************
Functions Prototypes
*******************************************************************************/
void usb0_host_interrupt(uint32_t int_sense);
void usb0_host_dma_interrupt_d0fifo(uint32_t int_sense);
void usb0_host_dma_interrupt_d1fifo(uint32_t int_sense);
uint16_t usb0_api_host_init(uint8_t int_level, uint16_t mode, uint16_t clockmode);
int32_t usb0_api_host_enumeration(uint16_t devadr);
int32_t usb0_api_host_detach(void);
int32_t usb0_api_host_data_in(uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t *data_buf);
int32_t usb0_api_host_data_out(uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t *data_buf);
int32_t usb0_api_host_control_transfer(uint16_t devadr, uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len, uint8_t *Buf);
int32_t usb0_api_host_set_endpoint(uint16_t devadr, USB_HOST_CFG_PIPETBL_t *user_table, uint8_t *configdescriptor);
int32_t usb0_api_host_clear_endpoint(USB_HOST_CFG_PIPETBL_t *user_table);
int32_t usb0_api_host_clear_endpoint_pipe(uint16_t pipe_sel, USB_HOST_CFG_PIPETBL_t *user_table);
uint16_t usb0_api_host_SetEndpointTable(uint16_t devadr, USB_HOST_CFG_PIPETBL_t *user_table, uint8_t* Table);
int32_t usb0_api_host_data_count(uint16_t pipe, uint32_t *data_count);
int32_t usb0_api_host_GetDeviceDescriptor(uint16_t devadr, uint16_t size, uint8_t *buf);
int32_t usb0_api_host_GetConfigDescriptor(uint16_t devadr, uint16_t size, uint8_t *buf);
int32_t usb0_api_host_SetConfig(uint16_t devadr, uint16_t confignum);
int32_t usb0_api_host_SetInterface(uint16_t devadr, uint16_t interface_alt, uint16_t interface_index);
int32_t usb0_api_host_ClearStall(uint16_t devadr, uint16_t ep_dir);
uint16_t usb0_api_host_GetUsbDeviceState(void);
void usb0_api_host_elt_4_4(void);
void usb0_api_host_elt_4_5(void);
void usb0_api_host_elt_4_6(void);
void usb0_api_host_elt_4_7(void);
void usb0_api_host_elt_4_8(void);
void usb0_api_host_elt_4_9(void);
void usb0_api_host_elt_get_desc(void);
void usb0_host_EL_ModeInit(void);
void usb0_host_EL_SetUACT(void);
void usb0_host_EL_ClearUACT(void);
void usb0_host_EL_SetTESTMODE(uint16_t mode);
void usb0_host_EL_ClearNRDYSTS(uint16_t pipe);
uint16_t usb0_host_EL_GetINTSTS1(void);
void usb0_host_EL_UsbBusReset(void);
void usb0_host_EL_UsbAttach(void);
void usb0_host_EL_SetupStage(uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len);
void usb0_host_EL_StatusStage(void);
void usb0_host_EL_CtrlReadStart(uint32_t Bsize, uint8_t *Table);
int32_t usb0_host_EL_UsbSuspend(void);
int32_t usb0_host_EL_UsbResume(void);
#if 0 /* prototype in devdrv_usb_host_api.h */
uint16_t Userdef_USB_usb0_host_d0fifo_dmaintid(void);
uint16_t Userdef_USB_usb0_host_d1fifo_dmaintid(void);
void Userdef_USB_usb0_host_attach(void);
void Userdef_USB_usb0_host_detach(void);
void Userdef_USB_usb0_host_delay_1ms(void);
void Userdef_USB_usb0_host_delay_xms(uint32_t msec);
void Userdef_USB_usb0_host_delay_10us(uint32_t usec);
void Userdef_USB_usb0_host_delay_500ns(void);
void Userdef_USB_usb0_host_start_dma(USB_HOST_DMA_t *dma, uint16_t dfacc);
uint32_t Userdef_USB_usb0_host_stop_dma0(void);
uint32_t Userdef_USB_usb0_host_stop_dma1(void);
#endif
#endif /* USB0_HOST_API_H */
/* End of File */

View file

@ -0,0 +1,139 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_dmacdrv.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB0_HOST_DMACDRV_H
#define USB0_HOST_DMACDRV_H
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
/*******************************************************************************
Typedef definitions
*******************************************************************************/
typedef struct dmac_transinfo
{
uint32_t src_addr; /* Transfer source address */
uint32_t dst_addr; /* Transfer destination address */
uint32_t count; /* Transfer byte count */
uint32_t src_size; /* Transfer source data size */
uint32_t dst_size; /* Transfer destination data size */
uint32_t saddr_dir; /* Transfer source address direction */
uint32_t daddr_dir; /* Transfer destination address direction */
} dmac_transinfo_t;
/*******************************************************************************
Macro definitions
*******************************************************************************/
/* ==== Transfer specification of the sample program ==== */
#define DMAC_SAMPLE_SINGLE (0) /* Single transfer */
#define DMAC_SAMPLE_CONTINUATION (1) /* Continuous transfer (use REN bit) */
/* ==== DMA modes ==== */
#define DMAC_MODE_REGISTER (0) /* Register mode */
#define DMAC_MODE_LINK (1) /* Link mode */
/* ==== Transfer requests ==== */
#define DMAC_REQ_MODE_EXT (0) /* External request */
#define DMAC_REQ_MODE_PERI (1) /* On-chip peripheral module request */
#define DMAC_REQ_MODE_SOFT (2) /* Auto-request (request by software) */
/* ==== DMAC transfer sizes ==== */
#define DMAC_TRANS_SIZE_8 (0) /* 8 bits */
#define DMAC_TRANS_SIZE_16 (1) /* 16 bits */
#define DMAC_TRANS_SIZE_32 (2) /* 32 bits */
#define DMAC_TRANS_SIZE_64 (3) /* 64 bits */
#define DMAC_TRANS_SIZE_128 (4) /* 128 bits */
#define DMAC_TRANS_SIZE_256 (5) /* 256 bits */
#define DMAC_TRANS_SIZE_512 (6) /* 512 bits */
#define DMAC_TRANS_SIZE_1024 (7) /* 1024 bits */
/* ==== Address increment for transferring ==== */
#define DMAC_TRANS_ADR_NO_INC (1) /* Not increment */
#define DMAC_TRANS_ADR_INC (0) /* Increment */
/* ==== Method for detecting DMA request ==== */
#define DMAC_REQ_DET_FALL (0) /* Falling edge detection */
#define DMAC_REQ_DET_RISE (1) /* Rising edge detection */
#define DMAC_REQ_DET_LOW (2) /* Low level detection */
#define DMAC_REQ_DET_HIGH (3) /* High level detection */
/* ==== Request Direction ==== */
#define DMAC_REQ_DIR_SRC (0) /* DMAREQ is the source/ DMAACK is active when reading */
#define DMAC_REQ_DIR_DST (1) /* DMAREQ is the destination/ DMAACK is active when writing */
/* ==== Descriptors ==== */
#define DMAC_DESC_HEADER (0) /* Header */
#define DMAC_DESC_SRC_ADDR (1) /* Source Address */
#define DMAC_DESC_DST_ADDR (2) /* Destination Address */
#define DMAC_DESC_COUNT (3) /* Transaction Byte */
#define DMAC_DESC_CHCFG (4) /* Channel Confg */
#define DMAC_DESC_CHITVL (5) /* Channel Interval */
#define DMAC_DESC_CHEXT (6) /* Channel Extension */
#define DMAC_DESC_LINK_ADDR (7) /* Link Address */
/* ==== On-chip peripheral module requests ===== */
typedef enum dmac_request_factor
{
DMAC_REQ_USB0_DMA0_TX, /* USB_0 channel 0 transmit FIFO empty */
DMAC_REQ_USB0_DMA0_RX, /* USB_0 channel 0 receive FIFO full */
DMAC_REQ_USB0_DMA1_TX, /* USB_0 channel 1 transmit FIFO empty */
DMAC_REQ_USB0_DMA1_RX, /* USB_0 channel 1 receive FIFO full */
DMAC_REQ_USB1_DMA0_TX, /* USB_1 channel 0 transmit FIFO empty */
DMAC_REQ_USB1_DMA0_RX, /* USB_1 channel 0 receive FIFO full */
DMAC_REQ_USB1_DMA1_TX, /* USB_1 channel 1 transmit FIFO empty */
DMAC_REQ_USB1_DMA1_RX, /* USB_1 channel 1 receive FIFO full */
} dmac_request_factor_t;
/*******************************************************************************
Variable Externs
*******************************************************************************/
/*******************************************************************************
Functions Prototypes
*******************************************************************************/
void usb0_host_DMAC1_PeriReqInit(const dmac_transinfo_t * trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction);
int32_t usb0_host_DMAC1_Open(uint32_t req);
void usb0_host_DMAC1_Close(uint32_t * remain);
void usb0_host_DMAC1_Load_Set(uint32_t src_addr, uint32_t dst_addr, uint32_t count);
void usb0_host_DMAC2_PeriReqInit(const dmac_transinfo_t * trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction);
int32_t usb0_host_DMAC2_Open(uint32_t req);
void usb0_host_DMAC2_Close(uint32_t * remain);
void usb0_host_DMAC2_Load_Set(uint32_t src_addr, uint32_t dst_addr, uint32_t count);
#endif /* USB0_HOST_DMACDRV_H */
/* End of File */

View file

@ -0,0 +1,355 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_dma.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host.h"
/* #include "usb0_host_dmacdrv.h" */
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
static void usb0_host_dmaint(uint16_t fifo);
static void usb0_host_dmaint_buf2fifo(uint16_t pipe);
static void usb0_host_dmaint_fifo2buf(uint16_t pipe);
/*******************************************************************************
* Function Name: usb0_host_dma_stop_d0
* Description : D0FIFO DMA stop
* Arguments : uint16_t pipe : pipe number
* : uint32_t remain : transfer byte
* Return Value : none
*******************************************************************************/
void usb0_host_dma_stop_d0 (uint16_t pipe, uint32_t remain)
{
uint16_t dtln;
uint16_t dfacc;
uint16_t buffer;
uint16_t sds_b = 1;
dfacc = RZA_IO_RegRead_16(&USB200.D0FBCFG,
USB_DnFBCFG_DFACC_SHIFT,
USB_DnFBCFG_DFACC);
if (dfacc == 2)
{
sds_b = 32;
}
else if (dfacc == 1)
{
sds_b = 16;
}
else
{
if (g_usb0_host_DmaInfo[USB_HOST_D0FIFO].size == 2)
{
sds_b = 4;
}
else if (g_usb0_host_DmaInfo[USB_HOST_D0FIFO].size == 1)
{
sds_b = 2;
}
else
{
sds_b = 1;
}
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
{
if (g_usb0_host_pipe_status[pipe] != USB_HOST_PIPE_DONE)
{
buffer = USB200.D0FIFOCTR;
dtln = (buffer & USB_HOST_BITDTLN);
if ((dtln % sds_b) != 0)
{
remain += (sds_b - (dtln % sds_b));
}
g_usb0_host_PipeDataSize[pipe] = (g_usb0_host_data_count[pipe] - remain);
g_usb0_host_data_count[pipe] = remain;
}
}
RZA_IO_RegWrite_16(&USB200.D0FIFOSEL,
0,
USB_DnFIFOSEL_DREQE_SHIFT,
USB_DnFIFOSEL_DREQE);
}
/*******************************************************************************
* Function Name: usb0_host_dma_stop_d1
* Description : D1FIFO DMA stop
* Arguments : uint16_t pipe : pipe number
* : uint32_t remain : transfer byte
* Return Value : none
*******************************************************************************/
void usb0_host_dma_stop_d1 (uint16_t pipe, uint32_t remain)
{
uint16_t dtln;
uint16_t dfacc;
uint16_t buffer;
uint16_t sds_b = 1;
dfacc = RZA_IO_RegRead_16(&USB200.D1FBCFG,
USB_DnFBCFG_DFACC_SHIFT,
USB_DnFBCFG_DFACC);
if (dfacc == 2)
{
sds_b = 32;
}
else if (dfacc == 1)
{
sds_b = 16;
}
else
{
if (g_usb0_host_DmaInfo[USB_HOST_D1FIFO].size == 2)
{
sds_b = 4;
}
else if (g_usb0_host_DmaInfo[USB_HOST_D1FIFO].size == 1)
{
sds_b = 2;
}
else
{
sds_b = 1;
}
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
{
if (g_usb0_host_pipe_status[pipe] != USB_HOST_PIPE_DONE)
{
buffer = USB200.D1FIFOCTR;
dtln = (buffer & USB_HOST_BITDTLN);
if ((dtln % sds_b) != 0)
{
remain += (sds_b - (dtln % sds_b));
}
g_usb0_host_PipeDataSize[pipe] = (g_usb0_host_data_count[pipe] - remain);
g_usb0_host_data_count[pipe] = remain;
}
}
RZA_IO_RegWrite_16(&USB200.D1FIFOSEL,
0,
USB_DnFIFOSEL_DREQE_SHIFT,
USB_DnFIFOSEL_DREQE);
}
/*******************************************************************************
* Function Name: usb0_host_dma_interrupt_d0fifo
* Description : This function is DMA interrupt handler entry.
* : Execute usb1_host_dmaint() after disabling DMA interrupt in this function.
* : Disable DMA interrupt to DMAC executed when USB_HOST_D0FIFO_DMA is
* : specified by dma->fifo.
* : Register this function as DMA complete interrupt.
* Arguments : uint32_t int_sense ; Interrupts detection mode
* : ; INTC_LEVEL_SENSITIVE : Level sense
* : ; INTC_EDGE_TRIGGER : Edge trigger
* Return Value : none
*******************************************************************************/
void usb0_host_dma_interrupt_d0fifo (uint32_t int_sense)
{
usb0_host_dmaint(USB_HOST_D0FIFO);
g_usb0_host_DmaStatus[USB_HOST_D0FIFO] = USB_HOST_DMA_READY;
}
/*******************************************************************************
* Function Name: usb0_host_dma_interrupt_d1fifo
* Description : This function is DMA interrupt handler entry.
* : Execute usb0_host_dmaint() after disabling DMA interrupt in this function.
* : Disable DMA interrupt to DMAC executed when USB_HOST_D1FIFO_DMA is
* : specified by dma->fifo.
* : Register this function as DMA complete interrupt.
* Arguments : uint32_t int_sense ; Interrupts detection mode
* : ; INTC_LEVEL_SENSITIVE : Level sense
* : ; INTC_EDGE_TRIGGER : Edge trigger
* Return Value : none
*******************************************************************************/
void usb0_host_dma_interrupt_d1fifo (uint32_t int_sense)
{
usb0_host_dmaint(USB_HOST_D1FIFO);
g_usb0_host_DmaStatus[USB_HOST_D1FIFO] = USB_HOST_DMA_READY;
}
/*******************************************************************************
* Function Name: usb0_host_dmaint
* Description : This function is DMA transfer end interrupt
* Arguments : uint16_t fifo ; fifo number
* : ; USB_HOST_D0FIFO
* : ; USB_HOST_D1FIFO
* Return Value : none
*******************************************************************************/
static void usb0_host_dmaint (uint16_t fifo)
{
uint16_t pipe;
pipe = g_usb0_host_DmaPipe[fifo];
if (g_usb0_host_DmaInfo[fifo].dir == USB_HOST_BUF2FIFO)
{
usb0_host_dmaint_buf2fifo(pipe);
}
else
{
usb0_host_dmaint_fifo2buf(pipe);
}
}
/*******************************************************************************
* Function Name: usb0_host_dmaint_fifo2buf
* Description : Executes read completion from FIFO by DMAC.
* Arguments : uint16_t pipe : pipe number
* Return Value : none
*******************************************************************************/
static void usb0_host_dmaint_fifo2buf (uint16_t pipe)
{
uint32_t remain;
uint16_t useport;
if (g_usb0_host_pipe_status[pipe] != USB_HOST_PIPE_DONE)
{
useport = (uint16_t)(g_usb0_host_PipeTbl[pipe] & USB_HOST_FIFO_USE);
if (useport == USB_HOST_D0FIFO_DMA)
{
remain = Userdef_USB_usb0_host_stop_dma0();
usb0_host_dma_stop_d0(pipe, remain);
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
if (g_usb0_host_DmaStatus[USB_HOST_D0FIFO] == USB_HOST_DMA_BUSYEND)
{
USB200.D0FIFOCTR = USB_HOST_BITBCLR;
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
else
{
usb0_host_enable_brdy_int(pipe);
}
}
}
else
{
remain = Userdef_USB_usb0_host_stop_dma1();
usb0_host_dma_stop_d1(pipe, remain);
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
if (g_usb0_host_DmaStatus[USB_HOST_D1FIFO] == USB_HOST_DMA_BUSYEND)
{
USB200.D1FIFOCTR = USB_HOST_BITBCLR;
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
else
{
usb0_host_enable_brdy_int(pipe);
}
}
}
}
}
/*******************************************************************************
* Function Name: usb0_host_dmaint_buf2fifo
* Description : Executes write completion in FIFO by DMAC.
* Arguments : uint16_t pipe : pipe number
* Return Value : none
*******************************************************************************/
static void usb0_host_dmaint_buf2fifo (uint16_t pipe)
{
uint16_t useport;
uint32_t remain;
useport = (uint16_t)(g_usb0_host_PipeTbl[pipe] & USB_HOST_FIFO_USE);
if (useport == USB_HOST_D0FIFO_DMA)
{
remain = Userdef_USB_usb0_host_stop_dma0();
usb0_host_dma_stop_d0(pipe, remain);
if (g_usb0_host_DmaBval[USB_HOST_D0FIFO] != 0)
{
RZA_IO_RegWrite_16(&USB200.D0FIFOCTR,
1,
USB_DnFIFOCTR_BVAL_SHIFT,
USB_DnFIFOCTR_BVAL);
}
}
else
{
remain = Userdef_USB_usb0_host_stop_dma1();
usb0_host_dma_stop_d1(pipe, remain);
if (g_usb0_host_DmaBval[USB_HOST_D1FIFO] != 0)
{
RZA_IO_RegWrite_16(&USB200.D1FIFOCTR,
1,
USB_DnFIFOCTR_BVAL_SHIFT,
USB_DnFIFOCTR_BVAL);
}
}
usb0_host_enable_bemp_int(pipe);
}
/* End of File */

View file

@ -0,0 +1,285 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_intrn.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host.h"
#if(1) /* ohci_wrapp */
#include "ohci_wrapp_RZ_A1_local.h"
#endif
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb0_host_brdy_int
* Description : Executes BRDY interrupt(USB_HOST_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_enb ; BRDYENB Register Value
* Return Value : none
*******************************************************************************/
void usb0_host_brdy_int (uint16_t status, uint16_t int_enb)
{
uint32_t int_sense = 0;
uint16_t pipe;
uint16_t pipebit;
for (pipe = USB_HOST_PIPE1; pipe <= USB_HOST_MAX_PIPE_NO; pipe++)
{
pipebit = g_usb0_host_bit_set[pipe];
if ((status & pipebit) && (int_enb & pipebit))
{
USB200.BRDYSTS = (uint16_t)~pipebit;
USB200.BEMPSTS = (uint16_t)~pipebit;
if ((g_usb0_host_PipeTbl[pipe] & USB_HOST_FIFO_USE) == USB_HOST_D0FIFO_DMA)
{
if (g_usb0_host_DmaStatus[USB_HOST_D0FIFO] != USB_HOST_DMA_READY)
{
usb0_host_dma_interrupt_d0fifo(int_sense);
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
usb0_host_read_dma(pipe);
usb0_host_disable_brdy_int(pipe);
}
else
{
USB200.D0FIFOCTR = USB_HOST_BITBCLR;
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
}
else if ((g_usb0_host_PipeTbl[pipe] & USB_HOST_FIFO_USE) == USB_HOST_D1FIFO_DMA)
{
if (g_usb0_host_DmaStatus[USB_HOST_D1FIFO] != USB_HOST_DMA_READY)
{
usb0_host_dma_interrupt_d1fifo(int_sense);
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
usb0_host_read_dma(pipe);
usb0_host_disable_brdy_int(pipe);
}
else
{
USB200.D1FIFOCTR = USB_HOST_BITBCLR;
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
}
else
{
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0)
{
usb0_host_read_buffer(pipe);
}
else
{
usb0_host_write_buffer(pipe);
}
}
#if(1) /* ohci_wrapp */
switch (g_usb0_host_pipe_status[pipe])
{
case USB_HOST_PIPE_DONE:
ohciwrapp_loc_TransEnd(pipe, TD_CC_NOERROR);
break;
case USB_HOST_PIPE_NORES:
case USB_HOST_PIPE_STALL:
case USB_HOST_PIPE_ERROR:
ohciwrapp_loc_TransEnd(pipe, TD_CC_STALL);
break;
default:
/* Do Nothing */
break;
}
#endif
}
}
}
/*******************************************************************************
* Function Name: usb0_host_nrdy_int
* Description : Executes NRDY interrupt(USB_HOST_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 USB_HOST_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
*******************************************************************************/
void usb0_host_nrdy_int (uint16_t status, uint16_t int_enb)
{
uint16_t pid;
uint16_t pipe;
uint16_t bitcheck;
bitcheck = (uint16_t)(status & int_enb);
USB200.NRDYSTS = (uint16_t)~status;
for (pipe = USB_HOST_PIPE1; pipe <= USB_HOST_MAX_PIPE_NO; pipe++)
{
if ((bitcheck&g_usb0_host_bit_set[pipe]) == g_usb0_host_bit_set[pipe])
{
if (RZA_IO_RegRead_16(&USB200.SYSCFG0,
USB_SYSCFG_DCFM_SHIFT,
USB_SYSCFG_DCFM) == 1)
{
if (g_usb0_host_pipe_status[pipe] == USB_HOST_PIPE_WAIT)
{
pid = usb0_host_get_pid(pipe);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_STALL;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(pipe, TD_CC_STALL);
#endif
}
else
{
#if(1) /* ohci_wrapp */
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_NORES;
ohciwrapp_loc_TransEnd(pipe, TD_CC_DEVICENOTRESPONDING);
#else
g_usb0_host_PipeIgnore[pipe]++;
if (g_usb0_host_PipeIgnore[pipe] == 3)
{
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_NORES;
}
else
{
usb0_host_set_pid_buf(pipe);
}
#endif
}
}
}
else
{
/* USB Function */
}
}
}
}
/*******************************************************************************
* Function Name: usb0_host_bemp_int
* Description : Executes BEMP interrupt(USB_HOST_PIPE1-9).
* Arguments : uint16_t status ; BEMPSTS Register Value
* : uint16_t int_enb ; BEMPENB Register Value
* Return Value : none
*******************************************************************************/
void usb0_host_bemp_int (uint16_t status, uint16_t int_enb)
{
uint16_t pid;
uint16_t pipe;
uint16_t bitcheck;
uint16_t inbuf;
bitcheck = (uint16_t)(status & int_enb);
USB200.BEMPSTS = (uint16_t)~status;
for (pipe = USB_HOST_PIPE1; pipe <= USB_HOST_MAX_PIPE_NO; pipe++)
{
if ((bitcheck&g_usb0_host_bit_set[pipe]) == g_usb0_host_bit_set[pipe])
{
pid = usb0_host_get_pid(pipe);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_STALL;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(pipe, TD_CC_STALL);
#endif
}
else
{
inbuf = usb0_host_get_inbuf(pipe);
if (inbuf == 0)
{
usb0_host_disable_bemp_int(pipe);
usb0_host_set_pid_nak(pipe);
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(pipe, TD_CC_NOERROR);
#endif
}
}
}
}
}
/* End of File */

View file

@ -0,0 +1,434 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_controlrw.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host.h"
#include "dev_drv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb0_host_CtrlTransStart
* Description : Executes USB control transfer.
* Arguments : uint16_t devadr ; device address
* : uint16_t Req ; bmRequestType & bRequest
* : uint16_t Val ; wValue
* : uint16_t Indx ; wIndex
* : uint16_t Len ; wLength
* : uint8_t *Buf ; Data buffer
* Return Value : DEVDRV_SUCCESS ; SUCCESS
* : DEVDRV_ERROR ; ERROR
*******************************************************************************/
int32_t usb0_host_CtrlTransStart (uint16_t devadr, uint16_t Req, uint16_t Val,
uint16_t Indx, uint16_t Len, uint8_t * Buf)
{
if (g_usb0_host_UsbDeviceSpeed == USB_HOST_LOW_SPEED)
{
RZA_IO_RegWrite_16(&USB200.SOFCFG,
1,
USB_SOFCFG_TRNENSEL_SHIFT,
USB_SOFCFG_TRNENSEL);
}
else
{
RZA_IO_RegWrite_16(&USB200.SOFCFG,
0,
USB_SOFCFG_TRNENSEL_SHIFT,
USB_SOFCFG_TRNENSEL);
}
USB200.DCPMAXP = (uint16_t)((uint16_t)(devadr << 12) + g_usb0_host_default_max_packet[devadr]);
if (g_usb0_host_pipe_status[USB_HOST_PIPE0] == USB_HOST_PIPE_IDLE)
{
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_WAIT;
g_usb0_host_PipeIgnore[USB_HOST_PIPE0] = 0; /* Ignore count clear */
g_usb0_host_CmdStage = (USB_HOST_STAGE_SETUP | USB_HOST_CMD_IDLE);
if (Len == 0)
{
g_usb0_host_CmdStage |= USB_HOST_MODE_NO_DATA; /* No-data Control */
}
else
{
if ((Req & 0x0080) != 0)
{
g_usb0_host_CmdStage |= USB_HOST_MODE_READ; /* Control Read */
}
else
{
g_usb0_host_CmdStage |= USB_HOST_MODE_WRITE; /* Control Write */
}
}
g_usb0_host_SavReq = Req; /* save request */
g_usb0_host_SavVal = Val;
g_usb0_host_SavIndx = Indx;
g_usb0_host_SavLen = Len;
}
else
{
if ((g_usb0_host_SavReq != Req) || (g_usb0_host_SavVal != Val)
|| (g_usb0_host_SavIndx != Indx) || (g_usb0_host_SavLen != Len))
{
return DEVDRV_ERROR;
}
}
switch ((g_usb0_host_CmdStage & (USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
/* --------------- SETUP STAGE --------------- */
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_IDLE):
usb0_host_SetupStage(Req, Val, Indx, Len);
break;
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_DOING):
/* do nothing */
break;
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_DONE): /* goto next stage */
g_usb0_host_PipeIgnore[USB_HOST_PIPE0] = 0; /* Ignore count clear */
switch ((g_usb0_host_CmdStage & (USB_HOST_MODE_FIELD)))
{
case USB_HOST_MODE_WRITE:
g_usb0_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb0_host_CmdStage |= USB_HOST_STAGE_DATA;
break;
case USB_HOST_MODE_READ:
g_usb0_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb0_host_CmdStage |= USB_HOST_STAGE_DATA;
break;
case USB_HOST_MODE_NO_DATA:
g_usb0_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb0_host_CmdStage |= USB_HOST_STAGE_STATUS;
break;
default:
break;
}
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_IDLE;
break;
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_NORES):
if (g_usb0_host_PipeIgnore[USB_HOST_PIPE0] == 3)
{
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
}
else
{
g_usb0_host_PipeIgnore[USB_HOST_PIPE0]++; /* Ignore count */
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_IDLE;
}
break;
/* --------------- DATA STAGE --------------- */
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_IDLE):
switch ((g_usb0_host_CmdStage & (USB_HOST_MODE_FIELD)))
{
case USB_HOST_MODE_WRITE:
usb0_host_CtrlWriteStart((uint32_t)Len, Buf);
break;
case USB_HOST_MODE_READ:
usb0_host_CtrlReadStart((uint32_t)Len, Buf);
break;
default:
break;
}
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
/* do nothing */
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DONE): /* goto next stage */
g_usb0_host_PipeIgnore[USB_HOST_PIPE0] = 0; /* Ignore count clear */
g_usb0_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb0_host_CmdStage |= USB_HOST_STAGE_STATUS;
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_IDLE;
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_NORES):
if (g_usb0_host_PipeIgnore[USB_HOST_PIPE0] == 3)
{
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
}
else
{
g_usb0_host_PipeIgnore[USB_HOST_PIPE0]++; /* Ignore count */
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DOING;
usb0_host_clear_pid_stall(USB_HOST_PIPE0);
usb0_host_set_pid_buf(USB_HOST_PIPE0);
}
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_STALL):
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL; /* exit STALL */
break;
/* --------------- STATUS STAGE --------------- */
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_IDLE):
usb0_host_StatusStage();
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
/* do nothing */
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DONE): /* end of Control transfer */
usb0_host_set_pid_nak(USB_HOST_PIPE0);
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_DONE; /* exit DONE */
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_NORES):
if (g_usb0_host_PipeIgnore[USB_HOST_PIPE0] == 3)
{
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
}
else
{
g_usb0_host_PipeIgnore[USB_HOST_PIPE0]++; /* Ignore count */
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DOING;
usb0_host_clear_pid_stall(USB_HOST_PIPE0);
usb0_host_set_pid_buf(USB_HOST_PIPE0);
}
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_STALL):
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL; /* exit STALL */
break;
default:
break;
}
if (g_usb0_host_pipe_status[USB_HOST_PIPE0] != USB_HOST_PIPE_WAIT)
{
RZA_IO_RegWrite_16(&USB200.SOFCFG,
0,
USB_SOFCFG_TRNENSEL_SHIFT,
USB_SOFCFG_TRNENSEL);
}
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb0_host_SetupStage
* Description : Executes USB control transfer/set up stage.
* Arguments : uint16_t Req ; bmRequestType & bRequest
* : uint16_t Val ; wValue
* : uint16_t Indx ; wIndex
* : uint16_t Len ; wLength
* Return Value : none
*******************************************************************************/
void usb0_host_SetupStage (uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len)
{
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DOING;
USB200.INTSTS1 = (uint16_t)~(USB_HOST_BITSACK | USB_HOST_BITSIGN); /* Status Clear */
USB200.USBREQ = Req;
USB200.USBVAL = Val;
USB200.USBINDX = Indx;
USB200.USBLENG = Len;
USB200.DCPCTR = USB_HOST_BITSUREQ; /* PID=NAK & Send Setup */
}
/*******************************************************************************
* Function Name: usb0_host_StatusStage
* Description : Executes USB control transfer/status stage.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_StatusStage (void)
{
uint8_t Buf1[16];
switch ((g_usb0_host_CmdStage & (USB_HOST_MODE_FIELD)))
{
case USB_HOST_MODE_READ:
usb0_host_CtrlWriteStart((uint32_t)0, (uint8_t *)&Buf1);
break;
case USB_HOST_MODE_WRITE:
usb0_host_CtrlReadStart((uint32_t)0, (uint8_t *)&Buf1);
break;
case USB_HOST_MODE_NO_DATA:
usb0_host_CtrlReadStart((uint32_t)0, (uint8_t *)&Buf1);
break;
default:
break;
}
}
/*******************************************************************************
* Function Name: usb0_host_CtrlWriteStart
* Description : Executes USB control transfer/data stage(write).
* Arguments : uint32_t Bsize ; Data Size
* : uint8_t *Table ; Data Table Address
* Return Value : USB_HOST_WRITESHRT ; End of data write
* : USB_HOST_WRITEEND ; End of data write (not null)
* : USB_HOST_WRITING ; Continue of data write
* : USB_HOST_FIFOERROR ; FIFO access error
*******************************************************************************/
uint16_t usb0_host_CtrlWriteStart (uint32_t Bsize, uint8_t * Table)
{
uint16_t EndFlag_K;
uint16_t mbw;
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DOING;
usb0_host_set_pid_nak(USB_HOST_PIPE0); /* Set NAK */
g_usb0_host_data_count[USB_HOST_PIPE0] = Bsize; /* Transfer size set */
g_usb0_host_data_pointer[USB_HOST_PIPE0] = Table; /* Transfer address set */
USB200.DCPCTR = USB_HOST_BITSQSET; /* SQSET=1, PID=NAK */
#if(1) /* ohci_wrapp */
Userdef_USB_usb0_host_delay_10us(3);
#endif
RZA_IO_RegWrite_16(&USB200.DCPCFG,
1,
USB_DCPCFG_DIR_SHIFT,
USB_DCPCFG_DIR);
mbw = usb0_host_get_mbw(g_usb0_host_data_count[USB_HOST_PIPE0], (uint32_t)g_usb0_host_data_pointer[USB_HOST_PIPE0]);
usb0_host_set_curpipe(USB_HOST_PIPE0, USB_HOST_CUSE, USB_HOST_BITISEL, mbw);
USB200.CFIFOCTR = USB_HOST_BITBCLR; /* Buffer Clear */
usb0_host_clear_pid_stall(USB_HOST_PIPE0);
EndFlag_K = usb0_host_write_buffer_c(USB_HOST_PIPE0);
/* Host Control sequence */
switch (EndFlag_K)
{
case USB_HOST_WRITESHRT: /* End of data write */
g_usb0_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb0_host_CmdStage |= USB_HOST_STAGE_STATUS;
usb0_host_enable_nrdy_int(USB_HOST_PIPE0); /* Error (NORES or STALL) */
usb0_host_enable_bemp_int(USB_HOST_PIPE0); /* Enable Empty Interrupt */
break;
case USB_HOST_WRITEEND: /* End of data write (not null) */
case USB_HOST_WRITING: /* Continue of data write */
usb0_host_enable_nrdy_int(USB_HOST_PIPE0); /* Error (NORES or STALL) */
usb0_host_enable_bemp_int(USB_HOST_PIPE0); /* Enable Empty Interrupt */
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
break;
default:
break;
}
usb0_host_set_pid_buf(USB_HOST_PIPE0); /* Set BUF */
return (EndFlag_K); /* End or Err or Continue */
}
/*******************************************************************************
* Function Name: usb0_host_CtrlReadStart
* Description : Executes USB control transfer/data stage(read).
* Arguments : uint32_t Bsize ; Data Size
* : uint8_t *Table ; Data Table Address
* Return Value : none
*******************************************************************************/
void usb0_host_CtrlReadStart (uint32_t Bsize, uint8_t * Table)
{
uint16_t mbw;
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DOING;
usb0_host_set_pid_nak(USB_HOST_PIPE0); /* Set NAK */
g_usb0_host_data_count[USB_HOST_PIPE0] = Bsize; /* Transfer size set */
g_usb0_host_data_pointer[USB_HOST_PIPE0] = Table; /* Transfer address set */
USB200.DCPCTR = USB_HOST_BITSQSET; /* SQSET=1, PID=NAK */
#if(1) /* ohci_wrapp */
Userdef_USB_usb0_host_delay_10us(3);
#endif
RZA_IO_RegWrite_16(&USB200.DCPCFG,
0,
USB_DCPCFG_DIR_SHIFT,
USB_DCPCFG_DIR);
mbw = usb0_host_get_mbw(g_usb0_host_data_count[USB_HOST_PIPE0], (uint32_t)g_usb0_host_data_pointer[USB_HOST_PIPE0]);
usb0_host_set_curpipe(USB_HOST_PIPE0, USB_HOST_CUSE, USB_HOST_NO, mbw);
USB200.CFIFOCTR = USB_HOST_BITBCLR; /* Buffer Clear */
usb0_host_enable_nrdy_int(USB_HOST_PIPE0); /* Error (NORES or STALL) */
usb0_host_enable_brdy_int(USB_HOST_PIPE0); /* Ok */
usb0_host_clear_pid_stall(USB_HOST_PIPE0);
usb0_host_set_pid_buf(USB_HOST_PIPE0); /* Set BUF */
}
/* End of File */

View file

@ -0,0 +1,889 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_drv_api.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host.h"
#include "dev_drv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb0_host_resetEP(USB_HOST_CFG_PIPETBL_t *tbl);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb0_api_host_init
* Description : Initializes USB module in the USB host mode.
* : USB connection is executed when executing this function in
* : the states that USB device isconnected to the USB port.
* Arguments : uint8_t int_level : USB Module interrupt level
* : USBU16 mode : USB_HOST_HIGH_SPEED
* : USB_HOST_FULL_SPEED
* : uint16_t clockmode : USB Clock mode
* Return Value : USB detach or attach
* : USB_HOST_ATTACH
* : USB_HOST_DETACH
*******************************************************************************/
uint16_t usb0_api_host_init (uint8_t int_level, uint16_t mode, uint16_t clockmode)
{
uint16_t connect;
volatile uint8_t dummy_buf;
CPG.STBCR7 &= 0xfd; /*The clock of USB0 modules is permitted */
dummy_buf = CPG.STBCR7; /* (Dummy read) */
g_usb0_host_SupportUsbDeviceSpeed = mode;
usb0_host_setting_interrupt(int_level);
usb0_host_reset_module(clockmode);
g_usb0_host_bchg_flag = USB_HOST_NO;
g_usb0_host_detach_flag = USB_HOST_NO;
g_usb0_host_attach_flag = USB_HOST_NO;
g_usb0_host_driver_state = USB_HOST_DRV_DETACHED;
g_usb0_host_default_max_packet[USB_HOST_DEVICE_0] = 64;
usb0_host_InitModule();
connect = usb0_host_CheckAttach();
if (connect == USB_HOST_ATTACH)
{
g_usb0_host_attach_flag = USB_HOST_YES;
}
else
{
usb0_host_UsbDetach2();
}
return connect;
}
#if(1) /* ohci_wrapp */
#else
/*******************************************************************************
* Function Name: usb0_api_host_enumeration
* Description : Initializes USB module in the USB host mode.
* : USB connection is executed when executing this function in
* : the states that USB device isconnected to the USB port.
* Arguments : uint16_t devadr : device address
* Return Value : DEVDRV_USBH_DETACH_ERR : device detach
* : DEVDRV_SUCCESS : device enumeration success
* : DEVDRV_ERROR : device enumeration error
*******************************************************************************/
int32_t usb0_api_host_enumeration (uint16_t devadr)
{
int32_t ret;
uint16_t driver_sts;
g_usb0_host_setUsbAddress = devadr;
while (1)
{
driver_sts = usb0_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
ret = DEVDRV_USBH_DETACH_ERR;
break;
}
else if (driver_sts == USB_HOST_DRV_CONFIGURED)
{
ret = DEVDRV_SUCCESS;
break;
}
else if (driver_sts == USB_HOST_DRV_STALL)
{
ret = DEVDRV_ERROR;
break;
}
else if (driver_sts == USB_HOST_DRV_NORES)
{
ret = DEVDRV_ERROR;
break;
}
else
{
/* Do Nothing */
}
}
if (driver_sts == USB_HOST_DRV_NORES)
{
while (1)
{
driver_sts = usb0_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
break;
}
}
}
return ret;
}
/*******************************************************************************
* Function Name: usb0_api_host_detach
* Description : USB detach routine
* Arguments : none
* Return Value : USB_HOST_DETACH : USB detach
* : USB_HOST_ATTACH : USB attach
* : DEVDRV_ERROR : error
*******************************************************************************/
int32_t usb0_api_host_detach (void)
{
int32_t ret;
uint16_t driver_sts;
while (1)
{
driver_sts = usb0_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
ret = USB_HOST_DETACH;
break;
}
else if (driver_sts == USB_HOST_DRV_CONFIGURED)
{
ret = USB_HOST_ATTACH;
break;
}
else if (driver_sts == USB_HOST_DRV_STALL)
{
ret = DEVDRV_ERROR;
break;
}
else if (driver_sts == USB_HOST_DRV_NORES)
{
ret = DEVDRV_ERROR;
break;
}
else
{
/* Do Nothing */
}
}
if (driver_sts == USB_HOST_DRV_NORES)
{
while (1)
{
driver_sts = usb0_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
break;
}
}
}
return ret;
}
/*******************************************************************************
* Function Name: usb0_api_host_data_in
* Description : Executes USB transfer as data-in in the argument specified pipe.
* Arguments : uint16_t devadr ; device address
* : uint16_t Pipe ; Pipe Number
* : uint32_t Size ; Data Size
* : uint8_t *data_buf ; Data data_buf Address
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb0_api_host_data_in (uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t * data_buf)
{
int32_t ret;
if (Pipe == USB_HOST_PIPE0)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipemaxp[Pipe], USB_PIPEMAXP_DEVSEL_SHIFT, USB_PIPEMAXP_DEVSEL) != devadr)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[Pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 1)
{
return DEVDRV_ERROR;
}
if (g_usb0_host_pipe_status[Pipe] == USB_HOST_PIPE_IDLE)
{
usb0_host_start_receive_transfer(Pipe, Size, data_buf);
}
else
{
return DEVDRV_ERROR; /* Now pipe is busy */
}
/* waiting for completing routine */
do
{
if (g_usb0_host_detach_flag == USB_HOST_YES)
{
break;
}
if ((g_usb0_host_pipe_status[Pipe] != USB_HOST_PIPE_IDLE) && (g_usb0_host_pipe_status[Pipe] != USB_HOST_PIPE_WAIT))
{
break;
}
} while (1);
if (g_usb0_host_detach_flag == USB_HOST_YES)
{
return DEVDRV_USBH_DETACH_ERR;
}
switch (g_usb0_host_pipe_status[Pipe])
{
case USB_HOST_PIPE_DONE:
ret = DEVDRV_SUCCESS;
break;
case USB_HOST_PIPE_STALL:
ret = DEVDRV_USBH_STALL;
break;
case USB_HOST_PIPE_NORES:
ret = DEVDRV_USBH_COM_ERR;
break;
default:
ret = DEVDRV_ERROR;
break;
}
usb0_host_stop_transfer(Pipe);
g_usb0_host_pipe_status[Pipe] = USB_HOST_PIPE_IDLE;
return ret;
}
/*******************************************************************************
* Function Name: usb0_api_host_data_out
* Description : Executes USB transfer as data-out in the argument specified pipe.
* Arguments : uint16_t devadr ; device address
* : uint16_t Pipe ; Pipe Number
* : uint32_t Size ; Data Size
* : uint8_t *data_buf ; Data data_buf Address
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb0_api_host_data_out (uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t * data_buf)
{
int32_t ret;
if (Pipe == USB_HOST_PIPE0)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipemaxp[Pipe], USB_PIPEMAXP_DEVSEL_SHIFT, USB_PIPEMAXP_DEVSEL) != devadr)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb0_host_pipecfg[Pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0)
{
return DEVDRV_ERROR;
}
if (g_usb0_host_pipe_status[Pipe] == USB_HOST_PIPE_IDLE)
{
usb0_host_start_send_transfer(Pipe, Size, data_buf);
}
else
{
return DEVDRV_ERROR; /* Now pipe is busy */
}
/* waiting for completing routine */
do
{
if (g_usb0_host_detach_flag == USB_HOST_YES)
{
break;
}
if ((g_usb0_host_pipe_status[Pipe] != USB_HOST_PIPE_IDLE) && (g_usb0_host_pipe_status[Pipe] != USB_HOST_PIPE_WAIT))
{
break;
}
} while (1);
if (g_usb0_host_detach_flag == USB_HOST_YES)
{
return DEVDRV_USBH_DETACH_ERR;
}
switch (g_usb0_host_pipe_status[Pipe])
{
case USB_HOST_PIPE_DONE:
ret = DEVDRV_SUCCESS;
break;
case USB_HOST_PIPE_STALL:
ret = DEVDRV_USBH_STALL;
break;
case USB_HOST_PIPE_NORES:
ret = DEVDRV_USBH_COM_ERR;
break;
default:
ret = DEVDRV_ERROR;
break;
}
usb0_host_stop_transfer(Pipe);
g_usb0_host_pipe_status[Pipe] = USB_HOST_PIPE_IDLE;
return ret;
}
/*******************************************************************************
* Function Name: usb0_api_host_control_transfer
* Description : Executes USB control transfer.
* Arguments : uint16_t devadr ; device address
* : uint16_t Req ; bmRequestType & bRequest
* : uint16_t Val ; wValue
* : uint16_t Indx ; wIndex
* : uint16_t Len ; wLength
* : uint8_t *buf ; Buffer
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_USBH_DETACH_ERR ; device detach
* : DEVDRV_USBH_CTRL_COM_ERR ; device no response
* : DEVDRV_USBH_STALL ; STALL
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb0_api_host_control_transfer (uint16_t devadr, uint16_t Req, uint16_t Val, uint16_t Indx,
uint16_t Len, uint8_t * Buf)
{
int32_t ret;
do
{
ret = usb0_host_CtrlTransStart(devadr, Req, Val, Indx, Len, Buf);
if (ret == DEVDRV_SUCCESS)
{
if (g_usb0_host_detach_flag == USB_HOST_YES)
{
break;
}
if ((g_usb0_host_pipe_status[USB_HOST_PIPE0] != USB_HOST_PIPE_IDLE)
&& (g_usb0_host_pipe_status[USB_HOST_PIPE0] != USB_HOST_PIPE_WAIT))
{
break;
}
}
else
{
return DEVDRV_ERROR;
}
} while (1);
if (g_usb0_host_detach_flag == USB_HOST_YES)
{
return DEVDRV_USBH_DETACH_ERR;
}
switch (g_usb0_host_pipe_status[USB_HOST_PIPE0])
{
case USB_HOST_PIPE_DONE:
ret = DEVDRV_SUCCESS;
break;
case USB_HOST_PIPE_STALL:
ret = DEVDRV_USBH_STALL;
break;
case USB_HOST_PIPE_NORES:
ret = DEVDRV_USBH_CTRL_COM_ERR;
break;
default:
ret = DEVDRV_ERROR;
break;
}
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_IDLE;
return ret;
}
/*******************************************************************************
* Function Name: usb0_api_host_set_endpoint
* Description : Sets end point on the information specified in the argument.
* Arguments : uint16_t devadr ; device address
* : uint8_t *configdescriptor ; device configration descriptor
* : USB_HOST_CFG_PIPETBL_t *user_table ; pipe table
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb0_api_host_set_endpoint (uint16_t devadr, USB_HOST_CFG_PIPETBL_t * user_table, uint8_t * configdescriptor)
{
uint16_t ret;
uint32_t end_point;
uint32_t offset;
uint32_t totalLength;
USB_HOST_CFG_PIPETBL_t * pipe_table;
/* End Point Search */
end_point = 0;
offset = configdescriptor[0];
totalLength = (uint16_t)(configdescriptor[2] + ((uint16_t)configdescriptor[3] << 8));
do
{
if (configdescriptor[offset + 1] == USB_HOST_ENDPOINT_DESC)
{
pipe_table = &user_table[end_point];
if (pipe_table->pipe_number == 0xffff)
{
break;
}
ret = usb0_api_host_SetEndpointTable(devadr, pipe_table, (uint8_t *)&configdescriptor[offset]);
if ((ret != USB_HOST_PIPE_IN) && (ret != USB_HOST_PIPE_OUT))
{
return DEVDRV_ERROR;
}
++end_point;
}
/* Next End Point Search */
offset += configdescriptor[offset];
} while (offset < totalLength);
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb0_api_host_clear_endpoint
* Description : Clears the pipe definition table specified in the argument.
* Arguments : USB_HOST_CFG_PIPETBL_t *user_table : pipe table
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb0_api_host_clear_endpoint (USB_HOST_CFG_PIPETBL_t * user_table)
{
uint16_t pipe;
for (pipe = USB_HOST_PIPE0; pipe <= USB_HOST_MAX_PIPE_NO; ++pipe)
{
if (user_table->pipe_number == 0xffff)
{
break;
}
user_table->pipe_cfg &= (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD);
user_table->pipe_max_pktsize = 0;
user_table->pipe_cycle = 0;
user_table++;
}
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb0_api_host_clear_endpoint_pipe
* Description : Clears the pipe definition table specified in the argument.
* Arguments : uint16_t pipe_sel : Pipe Number
* : USB_HOST_CFG_PIPETBL_t *user_table : pipe table
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb0_api_host_clear_endpoint_pipe (uint16_t pipe_sel, USB_HOST_CFG_PIPETBL_t * user_table)
{
uint16_t pipe;
for (pipe = USB_HOST_PIPE0; pipe <= USB_HOST_MAX_PIPE_NO; ++pipe)
{
if (user_table->pipe_number == 0xffff)
{
break;
}
if (user_table->pipe_number == pipe_sel)
{
user_table->pipe_cfg &= (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD);
user_table->pipe_max_pktsize = 0;
user_table->pipe_cycle = 0;
break;
}
user_table++;
}
return DEVDRV_SUCCESS;
}
#endif
/*******************************************************************************
* Function Name: usb0_api_host_SetEndpointTable
* Description : Sets the end point on the information specified by the argument.
* Arguments : uint16_t devadr : device address
* : USB_HOST_CFG_PIPETBL_t *user_table : pipe table
* : uint8_t *Table : Endpoint descriptor
* Return Value : USB_HOST_DIR_H_IN ; IN endpoint
* : USB_HOST_DIR_H_OUT ; OUT endpoint
* : USB_END_POINT_ERROR ; error
*******************************************************************************/
uint16_t usb0_api_host_SetEndpointTable (uint16_t devadr, USB_HOST_CFG_PIPETBL_t * user_table, uint8_t * Table)
{
uint16_t PipeCfg;
uint16_t PipeMaxp;
uint16_t pipe_number;
uint16_t ret;
uint16_t ret_flag = 0; // avoid warning.
pipe_number = user_table->pipe_number;
if (Table[1] != USB_HOST_ENDPOINT_DESC)
{
return USB_END_POINT_ERROR;
}
switch (Table[3] & USB_HOST_EP_TYPE)
{
case USB_HOST_EP_CNTRL:
ret_flag = USB_END_POINT_ERROR;
break;
case USB_HOST_EP_ISO:
if ((pipe_number != USB_HOST_PIPE1) && (pipe_number != USB_HOST_PIPE2))
{
return USB_END_POINT_ERROR;
}
PipeCfg = USB_HOST_ISO;
break;
case USB_HOST_EP_BULK:
if ((pipe_number < USB_HOST_PIPE1) || (pipe_number > USB_HOST_PIPE5))
{
return USB_END_POINT_ERROR;
}
PipeCfg = USB_HOST_BULK;
break;
case USB_HOST_EP_INT:
if ((pipe_number < USB_HOST_PIPE6) || (pipe_number > USB_HOST_PIPE9))
{
return USB_END_POINT_ERROR;
}
PipeCfg = USB_HOST_INTERRUPT;
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
/* Set pipe configuration table */
if ((Table[2] & USB_HOST_EP_DIR_MASK) == USB_HOST_EP_IN) /* IN(receive) */
{
if (PipeCfg == USB_HOST_ISO)
{
/* Transfer Type is ISO*/
PipeCfg |= USB_HOST_DIR_H_IN;
switch (user_table->fifo_port)
{
case USB_HOST_CUSE:
case USB_HOST_D0USE:
case USB_HOST_D1USE:
case USB_HOST_D0DMA:
case USB_HOST_D1DMA:
PipeCfg |= (uint16_t)(user_table->pipe_cfg & USB_HOST_DBLBFIELD);
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
}
else
{
/* Transfer Type is BULK or INT */
PipeCfg |= (USB_HOST_SHTNAKON | USB_HOST_DIR_H_IN); /* Compulsory SHTNAK */
switch (user_table->fifo_port)
{
case USB_HOST_CUSE:
case USB_HOST_D0USE:
case USB_HOST_D1USE:
PipeCfg |= (uint16_t)(user_table->pipe_cfg & (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD));
break;
case USB_HOST_D0DMA:
case USB_HOST_D1DMA:
PipeCfg |= (uint16_t)(user_table->pipe_cfg & (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD));
#ifdef __USB_DMA_BFRE_ENABLE__
/* this routine cannnot be perfomred if read operation is executed in buffer size */
PipeCfg |= USB_HOST_BFREON;
#endif
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
}
ret = USB_HOST_PIPE_IN;
}
else /* OUT(send) */
{
if (PipeCfg == USB_HOST_ISO)
{
/* Transfer Type is ISO*/
PipeCfg |= (uint16_t)(user_table->pipe_cfg & USB_HOST_DBLBFIELD);
}
else
{
/* Transfer Type is BULK or INT */
PipeCfg |= (uint16_t)(user_table->pipe_cfg & (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD));
}
PipeCfg |= USB_HOST_DIR_H_OUT;
ret = USB_HOST_PIPE_OUT;
}
switch (user_table->fifo_port)
{
case USB_HOST_CUSE:
g_usb0_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_CFIFO_USE;
break;
case USB_HOST_D0USE:
g_usb0_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D0FIFO_USE;
break;
case USB_HOST_D1USE:
g_usb0_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D1FIFO_USE;
break;
case USB_HOST_D0DMA:
g_usb0_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D0FIFO_DMA;
break;
case USB_HOST_D1DMA:
g_usb0_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D1FIFO_DMA;
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
/* Endpoint number set */
PipeCfg |= (uint16_t)(Table[2] & USB_HOST_EP_NUM_MASK);
g_usb0_host_PipeTbl[pipe_number] |= (uint16_t)(Table[2] & USB_HOST_EP_NUM_MASK);
/* Max packet size set */
PipeMaxp = (uint16_t)((uint16_t)Table[4] | (uint16_t)((uint16_t)Table[5] << 8));
if (PipeMaxp == 0u)
{
return USB_END_POINT_ERROR;
}
/* Set device address */
PipeMaxp |= (uint16_t)(devadr << 12);
user_table->pipe_cfg = PipeCfg;
user_table->pipe_max_pktsize = PipeMaxp;
usb0_host_resetEP(user_table);
return ret;
}
/*******************************************************************************
* Function Name: usb0_host_resetEP
* Description : Sets the end point on the information specified by the argument.
* Arguments : USB_HOST_CFG_PIPETBL_t *tbl : pipe table
* Return Value : none
*******************************************************************************/
static void usb0_host_resetEP (USB_HOST_CFG_PIPETBL_t * tbl)
{
uint16_t pipe;
/* Host pipe */
/* The pipe number of pipe definition table is obtained */
pipe = (uint16_t)(tbl->pipe_number & USB_HOST_BITCURPIPE); /* Pipe Number */
/* FIFO port access pipe is set to initial value */
/* The connection with FIFO should be cut before setting the pipe */
if (RZA_IO_RegRead_16(&USB200.CFIFOSEL,
USB_CFIFOSEL_CURPIPE_SHIFT,
USB_CFIFOSEL_CURPIPE) == pipe)
{
usb0_host_change_fifo_port(USB_HOST_PIPE0, USB_HOST_CUSE, USB_HOST_NO, USB_HOST_BITMBW_16);
}
if (RZA_IO_RegRead_16(&USB200.D0FIFOSEL,
USB_DnFIFOSEL_CURPIPE_SHIFT,
USB_DnFIFOSEL_CURPIPE) == pipe)
{
usb0_host_change_fifo_port(USB_HOST_PIPE0, USB_HOST_D0USE, USB_HOST_NO, USB_HOST_BITMBW_16);
}
if (RZA_IO_RegRead_16(&USB200.D1FIFOSEL,
USB_DnFIFOSEL_CURPIPE_SHIFT,
USB_DnFIFOSEL_CURPIPE) == pipe)
{
usb0_host_change_fifo_port(USB_HOST_PIPE0, USB_HOST_D1USE, USB_HOST_NO, USB_HOST_BITMBW_16);
}
/* Interrupt of pipe set is disabled */
usb0_host_disable_brdy_int(pipe);
usb0_host_disable_nrdy_int(pipe);
usb0_host_disable_bemp_int(pipe);
/* Pipe to set is set to NAK */
usb0_host_set_pid_nak(pipe);
/* Pipe is set */
USB200.PIPESEL = pipe;
USB200.PIPECFG = tbl->pipe_cfg;
USB200.PIPEBUF = tbl->pipe_buf;
USB200.PIPEMAXP = tbl->pipe_max_pktsize;
USB200.PIPEPERI = tbl->pipe_cycle;
g_usb0_host_pipecfg[pipe] = tbl->pipe_cfg;
g_usb0_host_pipebuf[pipe] = tbl->pipe_buf;
g_usb0_host_pipemaxp[pipe] = tbl->pipe_max_pktsize;
g_usb0_host_pipeperi[pipe] = tbl->pipe_cycle;
/* Sequence bit clear */
usb0_host_set_sqclr(pipe);
usb0_host_aclrm(pipe);
usb0_host_set_csclr(pipe);
/* Pipe window selection is set to unused */
USB200.PIPESEL = USB_HOST_PIPE0;
}
#if(1) /* ohci_wrapp */
#else
/*******************************************************************************
* Function Name: usb0_api_host_data_count
* Description : Get g_usb0_host_data_count[pipe]
* Arguments : uint16_t pipe ; Pipe Number
* : uint32_t *data_count ; return g_usb0_data_count[pipe]
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb0_api_host_data_count (uint16_t pipe, uint32_t * data_count)
{
if (pipe > USB_HOST_MAX_PIPE_NO)
{
return DEVDRV_ERROR;
}
*data_count = g_usb0_host_PipeDataSize[pipe];
return DEVDRV_SUCCESS;
}
#endif
/* End of File */

View file

@ -0,0 +1,137 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_global.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
const uint16_t g_usb0_host_bit_set[16] =
{
0x0001, 0x0002, 0x0004, 0x0008,
0x0010, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800,
0x1000, 0x2000, 0x4000, 0x8000
};
uint32_t g_usb0_host_data_count[USB_HOST_MAX_PIPE_NO + 1];
uint8_t * g_usb0_host_data_pointer[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb0_host_PipeIgnore[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb0_host_PipeTbl[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb0_host_pipe_status[USB_HOST_MAX_PIPE_NO + 1];
uint32_t g_usb0_host_PipeDataSize[USB_HOST_MAX_PIPE_NO + 1];
USB_HOST_DMA_t g_usb0_host_DmaInfo[2];
uint16_t g_usb0_host_DmaPipe[2];
uint16_t g_usb0_host_DmaBval[2];
uint16_t g_usb0_host_DmaStatus[2];
uint16_t g_usb0_host_driver_state;
uint16_t g_usb0_host_ConfigNum;
uint16_t g_usb0_host_CmdStage;
uint16_t g_usb0_host_bchg_flag;
uint16_t g_usb0_host_detach_flag;
uint16_t g_usb0_host_attach_flag;
uint16_t g_usb0_host_UsbAddress;
uint16_t g_usb0_host_setUsbAddress;
uint16_t g_usb0_host_default_max_packet[USB_HOST_MAX_DEVICE + 1];
uint16_t g_usb0_host_UsbDeviceSpeed;
uint16_t g_usb0_host_SupportUsbDeviceSpeed;
uint16_t g_usb0_host_SavReq;
uint16_t g_usb0_host_SavVal;
uint16_t g_usb0_host_SavIndx;
uint16_t g_usb0_host_SavLen;
uint16_t g_usb0_host_pipecfg[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb0_host_pipebuf[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb0_host_pipemaxp[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb0_host_pipeperi[USB_HOST_MAX_PIPE_NO + 1];
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb0_host_init_pipe_status
* Description : Initialize pipe status.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_init_pipe_status (void)
{
uint16_t loop;
g_usb0_host_ConfigNum = 0;
for (loop = 0; loop < (USB_HOST_MAX_PIPE_NO + 1); ++loop)
{
g_usb0_host_pipe_status[loop] = USB_HOST_PIPE_IDLE;
g_usb0_host_PipeDataSize[loop] = 0;
/* pipe configuration in usb0_host_resetEP() */
g_usb0_host_pipecfg[loop] = 0;
g_usb0_host_pipebuf[loop] = 0;
g_usb0_host_pipemaxp[loop] = 0;
g_usb0_host_pipeperi[loop] = 0;
}
}
/* End of File */

View file

@ -0,0 +1,496 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_usbint.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host.h"
#if(1) /* ohci_wrapp */
#include "ohci_wrapp_RZ_A1_local.h"
#endif
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb0_host_interrupt1(void);
static void usb0_host_BRDYInterrupt(uint16_t Status, uint16_t Int_enbl);
static void usb0_host_NRDYInterrupt(uint16_t Status, uint16_t Int_enbl);
static void usb0_host_BEMPInterrupt(uint16_t Status, uint16_t Int_enbl);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb0_host_interrupt
* Description : Executes USB interrupt.
* : Register this function in the USB interrupt handler.
* : Set CFIF0 in the pipe set before the interrupt after executing
* : this function.
* Arguments : uint32_t int_sense ; Interrupts detection mode
* : ; INTC_LEVEL_SENSITIVE : Level sense
* : ; INTC_EDGE_TRIGGER : Edge trigger
* Return Value : none
*******************************************************************************/
void usb0_host_interrupt (uint32_t int_sense)
{
uint16_t savepipe1;
uint16_t savepipe2;
uint16_t buffer;
savepipe1 = USB200.CFIFOSEL;
savepipe2 = USB200.PIPESEL;
usb0_host_interrupt1();
/* Control transmission changes ISEL within interruption processing. */
/* For this reason, write return of ISEL cannot be performed. */
buffer = USB200.CFIFOSEL;
buffer &= (uint16_t)~(USB_HOST_BITCURPIPE);
buffer |= (uint16_t)(savepipe1 & USB_HOST_BITCURPIPE);
USB200.CFIFOSEL = buffer;
USB200.PIPESEL = savepipe2;
}
/*******************************************************************************
* Function Name: usb0_host_interrupt1
* Description : Execue the USB interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_interrupt1 (void)
{
uint16_t intsts0;
uint16_t intsts1;
uint16_t intenb0;
uint16_t intenb1;
uint16_t brdysts;
uint16_t nrdysts;
uint16_t bempsts;
uint16_t brdyenb;
uint16_t nrdyenb;
uint16_t bempenb;
volatile uint16_t dumy_sts;
intsts0 = USB200.INTSTS0;
intsts1 = USB200.INTSTS1;
intenb0 = USB200.INTENB0;
intenb1 = USB200.INTENB1;
if ((intsts1 & USB_HOST_BITBCHG) && (intenb1 & USB_HOST_BITBCHGE))
{
USB200.INTSTS1 = (uint16_t)~USB_HOST_BITBCHG;
RZA_IO_RegWrite_16(&USB200.INTENB1,
0,
USB_INTENB1_BCHGE_SHIFT,
USB_INTENB1_BCHGE);
g_usb0_host_bchg_flag = USB_HOST_YES;
}
else if ((intsts1 & USB_HOST_BITSACK) && (intenb1 & USB_HOST_BITSACKE))
{
USB200.INTSTS1 = (uint16_t)~USB_HOST_BITSACK;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
#else
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
#endif
}
else if ((intsts1 & USB_HOST_BITSIGN) && (intenb1 & USB_HOST_BITSIGNE))
{
USB200.INTSTS1 = (uint16_t)~USB_HOST_BITSIGN;
#if(1) /* ohci_wrapp */
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#else
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_NORES;
#endif
}
else if (((intsts1 & USB_HOST_BITDTCH) == USB_HOST_BITDTCH)
&& ((intenb1 & USB_HOST_BITDTCHE) == USB_HOST_BITDTCHE))
{
USB200.INTSTS1 = (uint16_t)~USB_HOST_BITDTCH;
RZA_IO_RegWrite_16(&USB200.INTENB1,
0,
USB_INTENB1_DTCHE_SHIFT,
USB_INTENB1_DTCHE);
g_usb0_host_detach_flag = USB_HOST_YES;
Userdef_USB_usb0_host_detach();
usb0_host_UsbDetach2();
}
else if (((intsts1 & USB_HOST_BITATTCH) == USB_HOST_BITATTCH)
&& ((intenb1 & USB_HOST_BITATTCHE) == USB_HOST_BITATTCHE))
{
USB200.INTSTS1 = (uint16_t)~USB_HOST_BITATTCH;
RZA_IO_RegWrite_16(&USB200.INTENB1,
0,
USB_INTENB1_ATTCHE_SHIFT,
USB_INTENB1_ATTCHE);
g_usb0_host_attach_flag = USB_HOST_YES;
Userdef_USB_usb0_host_attach();
usb0_host_UsbAttach();
}
else if ((intsts0 & intenb0 & (USB_HOST_BITBEMP | USB_HOST_BITNRDY | USB_HOST_BITBRDY)))
{
brdysts = USB200.BRDYSTS;
nrdysts = USB200.NRDYSTS;
bempsts = USB200.BEMPSTS;
brdyenb = USB200.BRDYENB;
nrdyenb = USB200.NRDYENB;
bempenb = USB200.BEMPENB;
if ((intsts0 & USB_HOST_BITBRDY) && (intenb0 & USB_HOST_BITBRDYE) && (brdysts & brdyenb))
{
usb0_host_BRDYInterrupt(brdysts, brdyenb);
}
else if ((intsts0 & USB_HOST_BITBEMP) && (intenb0 & USB_HOST_BITBEMPE) && (bempsts & bempenb))
{
usb0_host_BEMPInterrupt(bempsts, bempenb);
}
else if ((intsts0 & USB_HOST_BITNRDY) && (intenb0 & USB_HOST_BITNRDYE) && (nrdysts & nrdyenb))
{
usb0_host_NRDYInterrupt(nrdysts, nrdyenb);
}
else
{
/* Do Nothing */
}
}
else
{
/* Do Nothing */
}
/* Three dummy read for clearing interrupt requests */
dumy_sts = USB200.INTSTS0;
dumy_sts = USB200.INTSTS1;
}
/*******************************************************************************
* Function Name: usb0_host_BRDYInterrupt
* Description : Executes USB BRDY interrupt.
* Arguments : uint16_t Status ; BRDYSTS Register Value
* : uint16_t Int_enbl ; BRDYENB Register Value
* Return Value : none
*******************************************************************************/
void usb0_host_BRDYInterrupt (uint16_t Status, uint16_t Int_enbl)
{
uint16_t buffer;
volatile uint16_t dumy_sts;
if ((Status & g_usb0_host_bit_set[USB_HOST_PIPE0]) && (Int_enbl & g_usb0_host_bit_set[USB_HOST_PIPE0]))
{
USB200.BRDYSTS = (uint16_t)~g_usb0_host_bit_set[USB_HOST_PIPE0];
#if(1) /* ohci_wrapp */
switch ((g_usb0_host_CmdStage & (USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
buffer = usb0_host_read_buffer_c(USB_HOST_PIPE0);
usb0_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb0_host_read_buffer_c(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_READING: /* Continue of data read */
break;
case USB_HOST_READEND: /* End of data read */
case USB_HOST_READSHRT: /* End of data read */
usb0_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case USB_HOST_READOVER: /* buffer over */
USB200.CFIFOCTR = USB_HOST_BITBCLR;
usb0_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
default:
break;
}
#else
switch ((g_usb0_host_CmdStage & (USB_HOST_MODE_FIELD | USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_MODE_WRITE | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
case (USB_HOST_MODE_NO_DATA | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
buffer = usb0_host_read_buffer_c(USB_HOST_PIPE0);
usb0_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case (USB_HOST_MODE_READ | USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb0_host_read_buffer_c(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_READING: /* Continue of data read */
break;
case USB_HOST_READEND: /* End of data read */
case USB_HOST_READSHRT: /* End of data read */
usb0_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case USB_HOST_READOVER: /* buffer over */
USB200.CFIFOCTR = USB_HOST_BITBCLR;
usb0_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
default:
break;
}
#endif
}
else
{
usb0_host_brdy_int(Status, Int_enbl);
}
/* Three dummy reads for clearing interrupt requests */
dumy_sts = USB200.BRDYSTS;
}
/*******************************************************************************
* Function Name: usb0_host_NRDYInterrupt
* Description : Executes USB NRDY interrupt.
* Arguments : uint16_t Status ; NRDYSTS Register Value
* : uint16_t Int_enbl ; NRDYENB Register Value
* Return Value : none
*******************************************************************************/
void usb0_host_NRDYInterrupt (uint16_t Status, uint16_t Int_enbl)
{
uint16_t pid;
volatile uint16_t dumy_sts;
if ((Status & g_usb0_host_bit_set[USB_HOST_PIPE0]) && (Int_enbl & g_usb0_host_bit_set[USB_HOST_PIPE0]))
{
USB200.NRDYSTS = (uint16_t)~g_usb0_host_bit_set[USB_HOST_PIPE0];
pid = usb0_host_get_pid(USB_HOST_PIPE0);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_STALL;
#if(1) /* ohci_wrapp */
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#endif
}
else if (pid == USB_HOST_PID_NAK)
{
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_NORES;
#if(1) /* ohci_wrapp */
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#endif
}
else
{
/* Do Nothing */
}
}
else
{
usb0_host_nrdy_int(Status, Int_enbl);
}
/* Three dummy reads for clearing interrupt requests */
dumy_sts = USB200.NRDYSTS;
}
/*******************************************************************************
* Function Name: usb0_host_BEMPInterrupt
* Description : Executes USB BEMP interrupt.
* Arguments : uint16_t Status ; BEMPSTS Register Value
* : uint16_t Int_enbl ; BEMPENB Register Value
* Return Value : none
*******************************************************************************/
void usb0_host_BEMPInterrupt (uint16_t Status, uint16_t Int_enbl)
{
uint16_t buffer;
uint16_t pid;
volatile uint16_t dumy_sts;
if ((Status & g_usb0_host_bit_set[USB_HOST_PIPE0]) && (Int_enbl & g_usb0_host_bit_set[USB_HOST_PIPE0]))
{
USB200.BEMPSTS = (uint16_t)~g_usb0_host_bit_set[USB_HOST_PIPE0];
pid = usb0_host_get_pid(USB_HOST_PIPE0);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_STALL;
#if(1) /* ohci_wrapp */
g_usb0_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL; /* exit STALL */
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#endif
}
else
{
#if(1) /* ohci_wrapp */
switch ((g_usb0_host_CmdStage & (USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb0_host_write_buffer(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_WRITING: /* Continue of data write */
case USB_HOST_WRITEEND: /* End of data write (zero-length) */
break;
case USB_HOST_WRITESHRT: /* End of data write */
g_usb0_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb0_host_CmdStage |= USB_HOST_STAGE_STATUS;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
default:
/* do nothing */
break;
}
#else
switch ((g_usb0_host_CmdStage & (USB_HOST_MODE_FIELD | USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_MODE_READ | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case (USB_HOST_MODE_WRITE | USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb0_host_write_buffer(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_WRITING: /* Continue of data write */
case USB_HOST_WRITEEND: /* End of data write (zero-length) */
break;
case USB_HOST_WRITESHRT: /* End of data write */
g_usb0_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb0_host_CmdStage |= USB_HOST_STAGE_STATUS;
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
case (USB_HOST_MODE_WRITE | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
g_usb0_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb0_host_CmdStage |= USB_HOST_CMD_IDLE;
break;
default:
/* do nothing */
break;
}
#endif
}
}
else
{
usb0_host_bemp_int(Status, Int_enbl);
}
/* Three dummy reads for clearing interrupt requests */
dumy_sts = USB200.BEMPSTS;
}
/* End of File */

View file

@ -0,0 +1,637 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_usbsig.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb0_host.h"
#include "dev_drv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb0_host_EnableINT_Module(void);
static void usb0_host_Enable_AttachINT(void);
static void usb0_host_Disable_AttachINT(void);
static void usb0_host_Disable_BchgINT(void);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb0_host_InitModule
* Description : Initializes the USB module in USB host module.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_InitModule (void)
{
uint16_t buf1;
uint16_t buf2;
uint16_t buf3;
usb0_host_init_pipe_status();
RZA_IO_RegWrite_16(&USB200.SYSCFG0,
1,
USB_SYSCFG_DCFM_SHIFT,
USB_SYSCFG_DCFM); /* HOST mode */
RZA_IO_RegWrite_16(&USB200.SYSCFG0,
1,
USB_SYSCFG_DRPD_SHIFT,
USB_SYSCFG_DRPD); /* PORT0 D+, D- setting */
do
{
buf1 = RZA_IO_RegRead_16(&USB200.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb0_host_delay_xms(50);
buf2 = RZA_IO_RegRead_16(&USB200.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb0_host_delay_xms(50);
buf3 = RZA_IO_RegRead_16(&USB200.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
} while ((buf1 != buf2) || (buf1 != buf3));
RZA_IO_RegWrite_16(&USB200.SYSCFG0,
1,
USB_SYSCFG_USBE_SHIFT,
USB_SYSCFG_USBE);
USB200.CFIFOSEL = (uint16_t)(USB_HOST_BITRCNT | USB_HOST_BITMBW_8 | USB_HOST_BITBYTE_LITTLE);
USB200.D0FIFOSEL = (uint16_t)( USB_HOST_BITMBW_8 | USB_HOST_BITBYTE_LITTLE);
USB200.D1FIFOSEL = (uint16_t)( USB_HOST_BITMBW_8 | USB_HOST_BITBYTE_LITTLE);
}
/*******************************************************************************
* Function Name: usb0_host_CheckAttach
* Description : Returns the USB device connection state.
* Arguments : none
* Return Value : uint16_t ; USB_HOST_ATTACH : Attached
* : ; USB_HOST_DETACH : not Attached
*******************************************************************************/
uint16_t usb0_host_CheckAttach (void)
{
uint16_t buf1;
uint16_t buf2;
uint16_t buf3;
uint16_t rhst;
do
{
buf1 = RZA_IO_RegRead_16(&USB200.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb0_host_delay_xms(50);
buf2 = RZA_IO_RegRead_16(&USB200.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb0_host_delay_xms(50);
buf3 = RZA_IO_RegRead_16(&USB200.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
} while ((buf1 != buf2) || (buf1 != buf3));
rhst = RZA_IO_RegRead_16(&USB200.DVSTCTR0,
USB_DVSTCTR0_RHST_SHIFT,
USB_DVSTCTR0_RHST);
if (rhst == USB_HOST_UNDECID)
{
if (buf1 == USB_HOST_FS_JSTS)
{
if (g_usb0_host_SupportUsbDeviceSpeed == USB_HOST_HIGH_SPEED)
{
RZA_IO_RegWrite_16(&USB200.SYSCFG0,
1,
USB_SYSCFG_HSE_SHIFT,
USB_SYSCFG_HSE);
}
else
{
RZA_IO_RegWrite_16(&USB200.SYSCFG0,
0,
USB_SYSCFG_HSE_SHIFT,
USB_SYSCFG_HSE);
}
return USB_HOST_ATTACH;
}
else if (buf1 == USB_HOST_LS_JSTS)
{
/* Low Speed Device */
RZA_IO_RegWrite_16(&USB200.SYSCFG0,
0,
USB_SYSCFG_HSE_SHIFT,
USB_SYSCFG_HSE);
return USB_HOST_ATTACH;
}
else
{
/* Do Nothing */
}
}
else if ((rhst == USB_HOST_HSMODE) || (rhst == USB_HOST_FSMODE))
{
return USB_HOST_ATTACH;
}
else if (rhst == USB_HOST_LSMODE)
{
return USB_HOST_ATTACH;
}
else
{
/* Do Nothing */
}
return USB_HOST_DETACH;
}
/*******************************************************************************
* Function Name: usb0_host_UsbAttach
* Description : Connects the USB device.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_UsbAttach (void)
{
usb0_host_EnableINT_Module();
usb0_host_Disable_BchgINT();
usb0_host_Disable_AttachINT();
usb0_host_Enable_DetachINT();
}
/*******************************************************************************
* Function Name: usb0_host_UsbDetach
* Description : Disconnects the USB device.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_UsbDetach (void)
{
uint16_t pipe;
uint16_t devadr;
g_usb0_host_driver_state = USB_HOST_DRV_DETACHED;
/* Terminate all the pipes in which communications on port */
/* are currently carried out */
for (pipe = 0; pipe < (USB_HOST_MAX_PIPE_NO + 1); ++pipe)
{
if (g_usb0_host_pipe_status[pipe] != USB_HOST_PIPE_IDLE)
{
if (pipe == USB_HOST_PIPE0)
{
devadr = RZA_IO_RegRead_16(&USB200.DCPMAXP,
USB_DCPMAXP_DEVSEL_SHIFT,
USB_DCPMAXP_DEVSEL);
}
else
{
devadr = RZA_IO_RegRead_16(&g_usb0_host_pipemaxp[pipe], USB_PIPEMAXP_DEVSEL_SHIFT, USB_PIPEMAXP_DEVSEL);
}
if (devadr == g_usb0_host_UsbAddress)
{
usb0_host_stop_transfer(pipe);
}
g_usb0_host_pipe_status[pipe] = USB_HOST_PIPE_IDLE;
}
}
g_usb0_host_ConfigNum = 0;
g_usb0_host_UsbAddress = 0;
g_usb0_host_default_max_packet[USB_HOST_DEVICE_0] = 64;
usb0_host_UsbDetach2();
}
/*******************************************************************************
* Function Name: usb0_host_UsbDetach2
* Description : Disconnects the USB device.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_UsbDetach2 (void)
{
usb0_host_Disable_DetachINT();
usb0_host_Disable_BchgINT();
usb0_host_Enable_AttachINT();
}
/*******************************************************************************
* Function Name: usb0_host_UsbBusReset
* Description : Issues the USB bus reset signal.
* Arguments : none
* Return Value : uint16_t ; RHST
*******************************************************************************/
uint16_t usb0_host_UsbBusReset (void)
{
uint16_t buffer;
uint16_t loop;
RZA_IO_RegWrite_16(&USB200.DVSTCTR0,
1,
USB_DVSTCTR0_USBRST_SHIFT,
USB_DVSTCTR0_USBRST);
RZA_IO_RegWrite_16(&USB200.DVSTCTR0,
0,
USB_DVSTCTR0_UACT_SHIFT,
USB_DVSTCTR0_UACT);
Userdef_USB_usb0_host_delay_xms(50);
buffer = USB200.DVSTCTR0;
buffer &= (uint16_t)(~(USB_HOST_BITRST));
buffer |= USB_HOST_BITUACT;
USB200.DVSTCTR0 = buffer;
Userdef_USB_usb0_host_delay_xms(20);
for (loop = 0, buffer = USB_HOST_HSPROC; loop < 3; ++loop)
{
buffer = RZA_IO_RegRead_16(&USB200.DVSTCTR0,
USB_DVSTCTR0_RHST_SHIFT,
USB_DVSTCTR0_RHST);
if (buffer == USB_HOST_HSPROC)
{
Userdef_USB_usb0_host_delay_xms(10);
}
else
{
break;
}
}
return buffer;
}
/*******************************************************************************
* Function Name: usb0_host_UsbResume
* Description : Issues the USB resume signal.
* Arguments : none
* Return Value : int32_t ; DEVDRV_SUCCESS
* : ; DEVDRV_ERROR
*******************************************************************************/
int32_t usb0_host_UsbResume (void)
{
uint16_t buf;
if ((g_usb0_host_driver_state & USB_HOST_DRV_SUSPEND) == 0)
{
/* not SUSPEND */
return DEVDRV_ERROR;
}
RZA_IO_RegWrite_16(&USB200.INTENB1,
0,
USB_INTENB1_BCHGE_SHIFT,
USB_INTENB1_BCHGE);
RZA_IO_RegWrite_16(&USB200.DVSTCTR0,
1,
USB_DVSTCTR0_RESUME_SHIFT,
USB_DVSTCTR0_RESUME);
Userdef_USB_usb0_host_delay_xms(20);
buf = USB200.DVSTCTR0;
buf &= (uint16_t)(~(USB_HOST_BITRESUME));
buf |= USB_HOST_BITUACT;
USB200.DVSTCTR0 = buf;
g_usb0_host_driver_state &= (uint16_t)~USB_HOST_DRV_SUSPEND;
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb0_host_UsbSuspend
* Description : Issues the USB suspend signal.
* Arguments : none
* Return Value : int32_t ; DEVDRV_SUCCESS :not SUSPEND
* : ; DEVDRV_ERROR :SUSPEND
*******************************************************************************/
int32_t usb0_host_UsbSuspend (void)
{
uint16_t buf;
if ((g_usb0_host_driver_state & USB_HOST_DRV_SUSPEND) != 0)
{
/* SUSPEND */
return DEVDRV_ERROR;
}
RZA_IO_RegWrite_16(&USB200.DVSTCTR0,
0,
USB_DVSTCTR0_UACT_SHIFT,
USB_DVSTCTR0_UACT);
Userdef_USB_usb0_host_delay_xms(5);
buf = RZA_IO_RegRead_16(&USB200.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
if ((buf != USB_HOST_FS_JSTS) && (buf != USB_HOST_LS_JSTS))
{
usb0_host_UsbDetach();
}
else
{
g_usb0_host_driver_state |= USB_HOST_DRV_SUSPEND;
}
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb0_host_Enable_DetachINT
* Description : Enables the USB disconnection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_Enable_DetachINT (void)
{
USB200.INTSTS1 = (uint16_t)(~(USB_HOST_BITDTCH));
RZA_IO_RegWrite_16(&USB200.INTENB1,
1,
USB_INTENB1_DTCHE_SHIFT,
USB_INTENB1_DTCHE);
}
/*******************************************************************************
* Function Name: usb0_host_Disable_DetachINT
* Description : Disables the USB disconnection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_Disable_DetachINT (void)
{
USB200.INTSTS1 = (uint16_t)(~(USB_HOST_BITDTCH));
RZA_IO_RegWrite_16(&USB200.INTENB1,
0,
USB_INTENB1_DTCHE_SHIFT,
USB_INTENB1_DTCHE);
}
/*******************************************************************************
* Function Name: usb0_host_Enable_AttachINT
* Description : Enables the USB connection detection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_Enable_AttachINT (void)
{
USB200.INTSTS1 = (uint16_t)(~(USB_HOST_BITATTCH));
RZA_IO_RegWrite_16(&USB200.INTENB1,
1,
USB_INTENB1_ATTCHE_SHIFT,
USB_INTENB1_ATTCHE);
}
/*******************************************************************************
* Function Name: usb0_host_Disable_AttachINT
* Description : Disables the USB connection detection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_Disable_AttachINT (void)
{
USB200.INTSTS1 = (uint16_t)(~(USB_HOST_BITATTCH));
RZA_IO_RegWrite_16(&USB200.INTENB1,
0,
USB_INTENB1_ATTCHE_SHIFT,
USB_INTENB1_ATTCHE);
}
/*******************************************************************************
* Function Name: usb0_host_Disable_BchgINT
* Description : Disables the USB bus change detection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_Disable_BchgINT (void)
{
USB200.INTSTS1 = (uint16_t)(~(USB_HOST_BITBCHG));
RZA_IO_RegWrite_16(&USB200.INTENB1,
0,
USB_INTENB1_BCHGE_SHIFT,
USB_INTENB1_BCHGE);
}
/*******************************************************************************
* Function Name: usb0_host_set_devadd
* Description : DEVADDn register is set by specified value
* Arguments : uint16_t addr : Device address
* : uint16_t *devadd : Set value
* Return Value : none
*******************************************************************************/
void usb0_host_set_devadd (uint16_t addr, uint16_t * devadd)
{
uint16_t * ptr;
uint16_t ret_flag = DEVDRV_FLAG_ON; // avoid warning.
switch (addr)
{
case USB_HOST_DEVICE_0:
ptr = (uint16_t *)&USB200.DEVADD0;
break;
case USB_HOST_DEVICE_1:
ptr = (uint16_t *)&USB200.DEVADD1;
break;
case USB_HOST_DEVICE_2:
ptr = (uint16_t *)&USB200.DEVADD2;
break;
case USB_HOST_DEVICE_3:
ptr = (uint16_t *)&USB200.DEVADD3;
break;
case USB_HOST_DEVICE_4:
ptr = (uint16_t *)&USB200.DEVADD4;
break;
case USB_HOST_DEVICE_5:
ptr = (uint16_t *)&USB200.DEVADD5;
break;
case USB_HOST_DEVICE_6:
ptr = (uint16_t *)&USB200.DEVADD6;
break;
case USB_HOST_DEVICE_7:
ptr = (uint16_t *)&USB200.DEVADD7;
break;
case USB_HOST_DEVICE_8:
ptr = (uint16_t *)&USB200.DEVADD8;
break;
case USB_HOST_DEVICE_9:
ptr = (uint16_t *)&USB200.DEVADD9;
break;
case USB_HOST_DEVICE_10:
ptr = (uint16_t *)&USB200.DEVADDA;
break;
default:
ret_flag = DEVDRV_FLAG_OFF;
break;
}
if (ret_flag == DEVDRV_FLAG_ON)
{
*ptr = (uint16_t)(*devadd & USB_HOST_DEVADD_MASK);
}
}
/*******************************************************************************
* Function Name: usb0_host_get_devadd
* Description : DEVADDn register is obtained
* Arguments : uint16_t addr : Device address
* : uint16_t *devadd : USB_HOST_DEVADD register value
* Return Value : none
*******************************************************************************/
void usb0_host_get_devadd (uint16_t addr, uint16_t * devadd)
{
uint16_t * ptr;
uint16_t ret_flag = DEVDRV_FLAG_ON; // avoid warning.
switch (addr)
{
case USB_HOST_DEVICE_0:
ptr = (uint16_t *)&USB200.DEVADD0;
break;
case USB_HOST_DEVICE_1:
ptr = (uint16_t *)&USB200.DEVADD1;
break;
case USB_HOST_DEVICE_2:
ptr = (uint16_t *)&USB200.DEVADD2;
break;
case USB_HOST_DEVICE_3:
ptr = (uint16_t *)&USB200.DEVADD3;
break;
case USB_HOST_DEVICE_4:
ptr = (uint16_t *)&USB200.DEVADD4;
break;
case USB_HOST_DEVICE_5:
ptr = (uint16_t *)&USB200.DEVADD5;
break;
case USB_HOST_DEVICE_6:
ptr = (uint16_t *)&USB200.DEVADD6;
break;
case USB_HOST_DEVICE_7:
ptr = (uint16_t *)&USB200.DEVADD7;
break;
case USB_HOST_DEVICE_8:
ptr = (uint16_t *)&USB200.DEVADD8;
break;
case USB_HOST_DEVICE_9:
ptr = (uint16_t *)&USB200.DEVADD9;
break;
case USB_HOST_DEVICE_10:
ptr = (uint16_t *)&USB200.DEVADDA;
break;
default:
ret_flag = DEVDRV_FLAG_OFF;
break;
}
if (ret_flag == DEVDRV_FLAG_ON)
{
*devadd = *ptr;
}
}
/*******************************************************************************
* Function Name: usb0_host_EnableINT_Module
* Description : Enables BEMP/NRDY/BRDY interrupt and SIGN/SACK interrupt.
* : Enables NRDY/BEMP interrupt in the pipe0.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb0_host_EnableINT_Module (void)
{
uint16_t buf;
buf = USB200.INTENB0;
buf |= (USB_HOST_BITBEMPE | USB_HOST_BITNRDYE | USB_HOST_BITBRDYE);
USB200.INTENB0 = buf;
buf = USB200.INTENB1;
buf |= (USB_HOST_BITSIGNE | USB_HOST_BITSACKE);
USB200.INTENB1 = buf;
usb0_host_enable_nrdy_int(USB_HOST_PIPE0);
usb0_host_enable_bemp_int(USB_HOST_PIPE0);
}
/* End of File */

View file

@ -0,0 +1,698 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_dmacdrv.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "r_typedefs.h"
#include "iodefine.h"
#include "rza_io_regrw.h"
#include "usb0_host_dmacdrv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
#define DMAC_INDEFINE (255) /* Macro definition when REQD bit is not used */
/* ==== Request setting information for on-chip peripheral module ==== */
typedef enum dmac_peri_req_reg_type
{
DMAC_REQ_MID,
DMAC_REQ_RID,
DMAC_REQ_AM,
DMAC_REQ_LVL,
DMAC_REQ_REQD
} dmac_peri_req_reg_type_t;
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/* ==== Prototype declaration ==== */
/* ==== Global variable ==== */
/* On-chip peripheral module request setting table */
static const uint8_t usb0_host_dmac_peri_req_init_table[8][5] =
{
/* MID,RID, AM,LVL,REQD */
{ 32, 3, 2, 1, 1}, /* USB_0 channel 0 transmit FIFO empty */
{ 32, 3, 2, 1, 0}, /* USB_0 channel 0 receive FIFO full */
{ 33, 3, 2, 1, 1}, /* USB_0 channel 1 transmit FIFO empty */
{ 33, 3, 2, 1, 0}, /* USB_0 channel 1 receive FIFO full */
{ 34, 3, 2, 1, 1}, /* USB_1 channel 0 transmit FIFO empty */
{ 34, 3, 2, 1, 0}, /* USB_1 channel 0 receive FIFO full */
{ 35, 3, 2, 1, 1}, /* USB_1 channel 1 transmit FIFO empty */
{ 35, 3, 2, 1, 0}, /* USB_1 channel 1 receive FIFO full */
};
/*******************************************************************************
* Function Name: usb0_host_DMAC1_PeriReqInit
* Description : Sets the register mode for DMA mode and the on-chip peripheral
* : module request for transfer request for DMAC channel 1.
* : Executes DMAC initial setting using the DMA information
* : specified by the argument *trans_info and the enabled/disabled
* : continuous transfer specified by the argument continuation.
* : Registers DMAC channel 1 interrupt handler function and sets
* : the interrupt priority level. Then enables transfer completion
* : interrupt.
* Arguments : dmac_transinfo_t * trans_info : Setting information to DMAC
* : : register
* : uint32_t dmamode : DMA mode (only for DMAC_MODE_REGISTER)
* : uint32_t continuation : Set continuous transfer to be valid
* : : after DMA transfer has been completed
* : DMAC_SAMPLE_CONTINUATION : Execute continuous transfer
* : DMAC_SAMPLE_SINGLE : Do not execute continuous
* : : transfer
* : uint32_t request_factor : Factor for on-chip peripheral module
* : : request
* : DMAC_REQ_OSTM0TINT : OSTM_0 compare match
* : DMAC_REQ_OSTM1TINT : OSTM_1 compare match
* : DMAC_REQ_TGI0A : MTU2_0 input capture/compare match
* : :
* : uint32_t req_direction : Setting value of CHCFG_n register
* : : REQD bit
* Return Value : none
*******************************************************************************/
void usb0_host_DMAC1_PeriReqInit (const dmac_transinfo_t * trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction)
{
/* ==== Register mode ==== */
if (DMAC_MODE_REGISTER == dmamode)
{
/* ==== Next0 register set ==== */
DMAC1.N0SA_n = trans_info->src_addr; /* Start address of transfer source */
DMAC1.N0DA_n = trans_info->dst_addr; /* Start address of transfer destination */
DMAC1.N0TB_n = trans_info->count; /* Total transfer byte count */
/* DAD : Transfer destination address counting direction */
/* SAD : Transfer source address counting direction */
/* DDS : Transfer destination transfer size */
/* SDS : Transfer source transfer size */
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
trans_info->daddr_dir,
DMAC1_CHCFG_n_DAD_SHIFT,
DMAC1_CHCFG_n_DAD);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
trans_info->saddr_dir,
DMAC1_CHCFG_n_SAD_SHIFT,
DMAC1_CHCFG_n_SAD);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
trans_info->dst_size,
DMAC1_CHCFG_n_DDS_SHIFT,
DMAC1_CHCFG_n_DDS);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
trans_info->src_size,
DMAC1_CHCFG_n_SDS_SHIFT,
DMAC1_CHCFG_n_SDS);
/* DMS : Register mode */
/* RSEL : Select Next0 register set */
/* SBE : No discharge of buffer data when aborted */
/* DEM : No DMA interrupt mask */
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_DMS_SHIFT,
DMAC1_CHCFG_n_DMS);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_RSEL_SHIFT,
DMAC1_CHCFG_n_RSEL);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_SBE_SHIFT,
DMAC1_CHCFG_n_SBE);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_DEM_SHIFT,
DMAC1_CHCFG_n_DEM);
/* ---- Continuous transfer ---- */
if (DMAC_SAMPLE_CONTINUATION == continuation)
{
/* REN : Execute continuous transfer */
/* RSW : Change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
1,
DMAC1_CHCFG_n_REN_SHIFT,
DMAC1_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
1,
DMAC1_CHCFG_n_RSW_SHIFT,
DMAC1_CHCFG_n_RSW);
}
/* ---- Single transfer ---- */
else
{
/* REN : Do not execute continuous transfer */
/* RSW : Do not change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_REN_SHIFT,
DMAC1_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_RSW_SHIFT,
DMAC1_CHCFG_n_RSW);
}
/* TM : Single transfer */
/* SEL : Channel setting */
/* HIEN, LOEN : On-chip peripheral module request */
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_TM_SHIFT,
DMAC1_CHCFG_n_TM);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
1,
DMAC1_CHCFG_n_SEL_SHIFT,
DMAC1_CHCFG_n_SEL);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
1,
DMAC1_CHCFG_n_HIEN_SHIFT,
DMAC1_CHCFG_n_HIEN);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
0,
DMAC1_CHCFG_n_LOEN_SHIFT,
DMAC1_CHCFG_n_LOEN);
/* ---- Set factor by specified on-chip peripheral module request ---- */
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_AM],
DMAC1_CHCFG_n_AM_SHIFT,
DMAC1_CHCFG_n_AM);
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_LVL],
DMAC1_CHCFG_n_LVL_SHIFT,
DMAC1_CHCFG_n_LVL);
if (usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD] != DMAC_INDEFINE)
{
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD],
DMAC1_CHCFG_n_REQD_SHIFT,
DMAC1_CHCFG_n_REQD);
}
else
{
RZA_IO_RegWrite_32(&DMAC1.CHCFG_n,
req_direction,
DMAC1_CHCFG_n_REQD_SHIFT,
DMAC1_CHCFG_n_REQD);
}
RZA_IO_RegWrite_32(&DMAC01.DMARS,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_RID],
DMAC01_DMARS_CH1_RID_SHIFT,
DMAC01_DMARS_CH1_RID);
RZA_IO_RegWrite_32(&DMAC01.DMARS,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_MID],
DMAC01_DMARS_CH1_MID_SHIFT,
DMAC01_DMARS_CH1_MID);
/* PR : Round robin mode */
RZA_IO_RegWrite_32(&DMAC07.DCTRL_0_7,
1,
DMAC07_DCTRL_0_7_PR_SHIFT,
DMAC07_DCTRL_0_7_PR);
}
}
/*******************************************************************************
* Function Name: usb0_host_DMAC1_Open
* Description : Enables DMAC channel 1 transfer.
* Arguments : uint32_t req : DMAC request mode
* Return Value : 0 : Succeeded in enabling DMA transfer
* : -1 : Failed to enable DMA transfer (due to DMA operation)
*******************************************************************************/
int32_t usb0_host_DMAC1_Open (uint32_t req)
{
int32_t ret;
volatile uint8_t dummy;
/* Transferable? */
if ((0 == RZA_IO_RegRead_32(&DMAC1.CHSTAT_n,
DMAC1_CHSTAT_n_EN_SHIFT,
DMAC1_CHSTAT_n_EN)) &&
(0 == RZA_IO_RegRead_32(&DMAC1.CHSTAT_n,
DMAC1_CHSTAT_n_TACT_SHIFT,
DMAC1_CHSTAT_n_TACT)))
{
/* Clear Channel Status Register */
RZA_IO_RegWrite_32(&DMAC1.CHCTRL_n,
1,
DMAC1_CHCTRL_n_SWRST_SHIFT,
DMAC1_CHCTRL_n_SWRST);
dummy = RZA_IO_RegRead_32(&DMAC1.CHCTRL_n,
DMAC1_CHCTRL_n_SWRST_SHIFT,
DMAC1_CHCTRL_n_SWRST);
/* Enable DMA transfer */
RZA_IO_RegWrite_32(&DMAC1.CHCTRL_n,
1,
DMAC1_CHCTRL_n_SETEN_SHIFT,
DMAC1_CHCTRL_n_SETEN);
/* ---- Request by software ---- */
if (DMAC_REQ_MODE_SOFT == req)
{
/* DMA transfer Request by software */
RZA_IO_RegWrite_32(&DMAC1.CHCTRL_n,
1,
DMAC1_CHCTRL_n_STG_SHIFT,
DMAC1_CHCTRL_n_STG);
}
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************
* Function Name: usb0_host_DMAC1_Close
* Description : Aborts DMAC channel 1 transfer. Returns the remaining transfer
* : byte count at the time of DMA transfer abort to the argument
* : *remain.
* Arguments : uint32_t * remain : Remaining transfer byte count when
* : : DMA transfer is aborted
* Return Value : none
*******************************************************************************/
void usb0_host_DMAC1_Close (uint32_t * remain)
{
/* ==== Abort transfer ==== */
RZA_IO_RegWrite_32(&DMAC1.CHCTRL_n,
1,
DMAC1_CHCTRL_n_CLREN_SHIFT,
DMAC1_CHCTRL_n_CLREN);
while (1 == RZA_IO_RegRead_32(&DMAC1.CHSTAT_n,
DMAC1_CHSTAT_n_TACT_SHIFT,
DMAC1_CHSTAT_n_TACT))
{
/* Loop until transfer is aborted */
}
while (1 == RZA_IO_RegRead_32(&DMAC1.CHSTAT_n,
DMAC1_CHSTAT_n_EN_SHIFT,
DMAC1_CHSTAT_n_EN))
{
/* Loop until 0 is set in EN before checking the remaining transfer byte count */
}
/* ==== Obtain remaining transfer byte count ==== */
*remain = DMAC1.CRTB_n;
}
/*******************************************************************************
* Function Name: usb0_host_DMAC1_Load_Set
* Description : Sets the transfer source address, transfer destination
* : address, and total transfer byte count respectively
* : specified by the argument src_addr, dst_addr, and count to
* : DMAC channel 1 as DMA transfer information.
* : Sets the register set selected by the CHCFG_n register
* : RSEL bit from the Next0 or Next1 register set.
* : This function should be called when DMA transfer of DMAC
* : channel 1 is aboted.
* Arguments : uint32_t src_addr : Transfer source address
* : uint32_t dst_addr : Transfer destination address
* : uint32_t count : Total transfer byte count
* Return Value : none
*******************************************************************************/
void usb0_host_DMAC1_Load_Set (uint32_t src_addr, uint32_t dst_addr, uint32_t count)
{
uint8_t reg_set;
/* Obtain register set in use */
reg_set = RZA_IO_RegRead_32(&DMAC1.CHSTAT_n,
DMAC1_CHSTAT_n_SR_SHIFT,
DMAC1_CHSTAT_n_SR);
/* ==== Load ==== */
if (0 == reg_set)
{
/* ---- Next0 Register Set ---- */
DMAC1.N0SA_n = src_addr; /* Start address of transfer source */
DMAC1.N0DA_n = dst_addr; /* Start address of transfer destination */
DMAC1.N0TB_n = count; /* Total transfer byte count */
}
else
{
/* ---- Next1 Register Set ---- */
DMAC1.N1SA_n = src_addr; /* Start address of transfer source */
DMAC1.N1DA_n = dst_addr; /* Start address of transfer destination */
DMAC1.N1TB_n = count; /* Total transfer byte count */
}
}
/*******************************************************************************
* Function Name: usb0_host_DMAC2_PeriReqInit
* Description : Sets the register mode for DMA mode and the on-chip peripheral
* : module request for transfer request for DMAC channel 2.
* : Executes DMAC initial setting using the DMA information
* : specified by the argument *trans_info and the enabled/disabled
* : continuous transfer specified by the argument continuation.
* : Registers DMAC channel 2 interrupt handler function and sets
* : the interrupt priority level. Then enables transfer completion
* : interrupt.
* Arguments : dmac_transinfo_t * trans_info : Setting information to DMAC
* : : register
* : uint32_t dmamode : DMA mode (only for DMAC_MODE_REGISTER)
* : uint32_t continuation : Set continuous transfer to be valid
* : : after DMA transfer has been completed
* : DMAC_SAMPLE_CONTINUATION : Execute continuous transfer
* : DMAC_SAMPLE_SINGLE : Do not execute continuous
* : : transfer
* : uint32_t request_factor : Factor for on-chip peripheral module
* : : request
* : DMAC_REQ_OSTM0TINT : OSTM_0 compare match
* : DMAC_REQ_OSTM1TINT : OSTM_1 compare match
* : DMAC_REQ_TGI0A : MTU2_0 input capture/compare match
* : :
* : uint32_t req_direction : Setting value of CHCFG_n register
* : : REQD bit
* Return Value : none
*******************************************************************************/
void usb0_host_DMAC2_PeriReqInit (const dmac_transinfo_t * trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction)
{
/* ==== Register mode ==== */
if (DMAC_MODE_REGISTER == dmamode)
{
/* ==== Next0 register set ==== */
DMAC2.N0SA_n = trans_info->src_addr; /* Start address of transfer source */
DMAC2.N0DA_n = trans_info->dst_addr; /* Start address of transfer destination */
DMAC2.N0TB_n = trans_info->count; /* Total transfer byte count */
/* DAD : Transfer destination address counting direction */
/* SAD : Transfer source address counting direction */
/* DDS : Transfer destination transfer size */
/* SDS : Transfer source transfer size */
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
trans_info->daddr_dir,
DMAC2_CHCFG_n_DAD_SHIFT,
DMAC2_CHCFG_n_DAD);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
trans_info->saddr_dir,
DMAC2_CHCFG_n_SAD_SHIFT,
DMAC2_CHCFG_n_SAD);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
trans_info->dst_size,
DMAC2_CHCFG_n_DDS_SHIFT,
DMAC2_CHCFG_n_DDS);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
trans_info->src_size,
DMAC2_CHCFG_n_SDS_SHIFT,
DMAC2_CHCFG_n_SDS);
/* DMS : Register mode */
/* RSEL : Select Next0 register set */
/* SBE : No discharge of buffer data when aborted */
/* DEM : No DMA interrupt mask */
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_DMS_SHIFT,
DMAC2_CHCFG_n_DMS);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_RSEL_SHIFT,
DMAC2_CHCFG_n_RSEL);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_SBE_SHIFT,
DMAC2_CHCFG_n_SBE);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_DEM_SHIFT,
DMAC2_CHCFG_n_DEM);
/* ---- Continuous transfer ---- */
if (DMAC_SAMPLE_CONTINUATION == continuation)
{
/* REN : Execute continuous transfer */
/* RSW : Change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
1,
DMAC2_CHCFG_n_REN_SHIFT,
DMAC2_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
1,
DMAC2_CHCFG_n_RSW_SHIFT,
DMAC2_CHCFG_n_RSW);
}
/* ---- Single transfer ---- */
else
{
/* REN : Do not execute continuous transfer */
/* RSW : Do not change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_REN_SHIFT,
DMAC2_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_RSW_SHIFT,
DMAC2_CHCFG_n_RSW);
}
/* TM : Single transfer */
/* SEL : Channel setting */
/* HIEN, LOEN : On-chip peripheral module request */
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_TM_SHIFT,
DMAC2_CHCFG_n_TM);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
2,
DMAC2_CHCFG_n_SEL_SHIFT,
DMAC2_CHCFG_n_SEL);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
1,
DMAC2_CHCFG_n_HIEN_SHIFT,
DMAC2_CHCFG_n_HIEN);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
0,
DMAC2_CHCFG_n_LOEN_SHIFT,
DMAC2_CHCFG_n_LOEN);
/* ---- Set factor by specified on-chip peripheral module request ---- */
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_AM],
DMAC2_CHCFG_n_AM_SHIFT,
DMAC2_CHCFG_n_AM);
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_LVL],
DMAC2_CHCFG_n_LVL_SHIFT,
DMAC2_CHCFG_n_LVL);
if (usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD] != DMAC_INDEFINE)
{
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD],
DMAC2_CHCFG_n_REQD_SHIFT,
DMAC2_CHCFG_n_REQD);
}
else
{
RZA_IO_RegWrite_32(&DMAC2.CHCFG_n,
req_direction,
DMAC2_CHCFG_n_REQD_SHIFT,
DMAC2_CHCFG_n_REQD);
}
RZA_IO_RegWrite_32(&DMAC23.DMARS,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_RID],
DMAC23_DMARS_CH2_RID_SHIFT,
DMAC23_DMARS_CH2_RID);
RZA_IO_RegWrite_32(&DMAC23.DMARS,
usb0_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_MID],
DMAC23_DMARS_CH2_MID_SHIFT,
DMAC23_DMARS_CH2_MID);
/* PR : Round robin mode */
RZA_IO_RegWrite_32(&DMAC07.DCTRL_0_7,
1,
DMAC07_DCTRL_0_7_PR_SHIFT,
DMAC07_DCTRL_0_7_PR);
}
}
/*******************************************************************************
* Function Name: usb0_host_DMAC2_Open
* Description : Enables DMAC channel 2 transfer.
* Arguments : uint32_t req : DMAC request mode
* Return Value : 0 : Succeeded in enabling DMA transfer
* : -1 : Failed to enable DMA transfer (due to DMA operation)
*******************************************************************************/
int32_t usb0_host_DMAC2_Open (uint32_t req)
{
int32_t ret;
volatile uint8_t dummy;
/* Transferable? */
if ((0 == RZA_IO_RegRead_32(&DMAC2.CHSTAT_n,
DMAC2_CHSTAT_n_EN_SHIFT,
DMAC2_CHSTAT_n_EN)) &&
(0 == RZA_IO_RegRead_32(&DMAC2.CHSTAT_n,
DMAC2_CHSTAT_n_TACT_SHIFT,
DMAC2_CHSTAT_n_TACT)))
{
/* Clear Channel Status Register */
RZA_IO_RegWrite_32(&DMAC2.CHCTRL_n,
1,
DMAC2_CHCTRL_n_SWRST_SHIFT,
DMAC2_CHCTRL_n_SWRST);
dummy = RZA_IO_RegRead_32(&DMAC2.CHCTRL_n,
DMAC2_CHCTRL_n_SWRST_SHIFT,
DMAC2_CHCTRL_n_SWRST);
/* Enable DMA transfer */
RZA_IO_RegWrite_32(&DMAC2.CHCTRL_n,
1,
DMAC2_CHCTRL_n_SETEN_SHIFT,
DMAC2_CHCTRL_n_SETEN);
/* ---- Request by software ---- */
if (DMAC_REQ_MODE_SOFT == req)
{
/* DMA transfer Request by software */
RZA_IO_RegWrite_32(&DMAC2.CHCTRL_n,
1,
DMAC2_CHCTRL_n_STG_SHIFT,
DMAC2_CHCTRL_n_STG);
}
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************
* Function Name: usb0_host_DMAC2_Close
* Description : Aborts DMAC channel 2 transfer. Returns the remaining transfer
* : byte count at the time of DMA transfer abort to the argument
* : *remain.
* Arguments : uint32_t * remain : Remaining transfer byte count when
* : : DMA transfer is aborted
* Return Value : none
*******************************************************************************/
void usb0_host_DMAC2_Close (uint32_t * remain)
{
/* ==== Abort transfer ==== */
RZA_IO_RegWrite_32(&DMAC2.CHCTRL_n,
1,
DMAC2_CHCTRL_n_CLREN_SHIFT,
DMAC2_CHCTRL_n_CLREN);
while (1 == RZA_IO_RegRead_32(&DMAC2.CHSTAT_n,
DMAC2_CHSTAT_n_TACT_SHIFT,
DMAC2_CHSTAT_n_TACT))
{
/* Loop until transfer is aborted */
}
while (1 == RZA_IO_RegRead_32(&DMAC2.CHSTAT_n,
DMAC2_CHSTAT_n_EN_SHIFT,
DMAC2_CHSTAT_n_EN))
{
/* Loop until 0 is set in EN before checking the remaining transfer byte count */
}
/* ==== Obtain remaining transfer byte count ==== */
*remain = DMAC2.CRTB_n;
}
/*******************************************************************************
* Function Name: usb0_host_DMAC2_Load_Set
* Description : Sets the transfer source address, transfer destination
* : address, and total transfer byte count respectively
* : specified by the argument src_addr, dst_addr, and count to
* : DMAC channel 2 as DMA transfer information.
* : Sets the register set selected by the CHCFG_n register
* : RSEL bit from the Next0 or Next1 register set.
* : This function should be called when DMA transfer of DMAC
* : channel 2 is aboted.
* Arguments : uint32_t src_addr : Transfer source address
* : uint32_t dst_addr : Transfer destination address
* : uint32_t count : Total transfer byte count
* Return Value : none
*******************************************************************************/
void usb0_host_DMAC2_Load_Set (uint32_t src_addr, uint32_t dst_addr, uint32_t count)
{
uint8_t reg_set;
/* Obtain register set in use */
reg_set = RZA_IO_RegRead_32(&DMAC2.CHSTAT_n,
DMAC2_CHSTAT_n_SR_SHIFT,
DMAC2_CHSTAT_n_SR);
/* ==== Load ==== */
if (0 == reg_set)
{
/* ---- Next0 Register Set ---- */
DMAC2.N0SA_n = src_addr; /* Start address of transfer source */
DMAC2.N0DA_n = dst_addr; /* Start address of transfer destination */
DMAC2.N0TB_n = count; /* Total transfer byte count */
}
else
{
/* ---- Next1 Register Set ---- */
DMAC2.N1SA_n = src_addr; /* Start address of transfer source */
DMAC2.N1DA_n = dst_addr; /* Start address of transfer destination */
DMAC2.N1TB_n = count; /* Total transfer byte count */
}
}
/* End of File */

View file

@ -0,0 +1,778 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb0_host_userdef.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include <stdio.h>
#include "cmsis_os.h"
#include "r_typedefs.h"
#include "iodefine.h"
#include "devdrv_usb_host_api.h"
#include "usb0_host.h"
#include "MBRZA1H.h" /* INTC Driver Header */
#include "usb0_host_dmacdrv.h"
#include "ohci_wrapp_RZ_A1_local.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
#define DUMMY_ACCESS OSTM0CNT
/* #define CACHE_WRITEBACK */
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
extern int32_t io_cwb(unsigned long start, unsigned long end);
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb0_host_enable_dmac0(uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc);
static void usb0_host_enable_dmac1(uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc);
static void Userdef_USB_usb0_host_delay_10us_2(void);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_d0fifo_dmaintid
* Description : get D0FIFO DMA Interrupt ID
* Arguments : none
* Return Value : D0FIFO DMA Interrupt ID
*******************************************************************************/
uint16_t Userdef_USB_usb0_host_d0fifo_dmaintid (void)
{
#if(1) /* ohci_wrapp */
return 0xFFFF;
#else
return DMAINT1_IRQn;
#endif
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_d1fifo_dmaintid
* Description : get D1FIFO DMA Interrupt ID
* Arguments : none
* Return Value : D1FIFO DMA Interrupt ID
*******************************************************************************/
uint16_t Userdef_USB_usb0_host_d1fifo_dmaintid (void)
{
#if(1) /* ohci_wrapp */
return 0xFFFF;
#else
return DMAINT2_IRQn;
#endif
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_attach
* Description : Wait for the software of 1ms.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_attach (void)
{
// printf("\n");
// printf("channel 0 attach device\n");
// printf("\n");
ohciwrapp_loc_Connect(1);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_detach
* Description : Wait for the software of 1ms.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_detach (void)
{
// printf("\n");
// printf("channel 0 detach device\n");
// printf("\n");
ohciwrapp_loc_Connect(0);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_delay_1ms
* Description : Wait for the software of 1ms.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_delay_1ms (void)
{
osDelay(1);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_delay_xms
* Description : Wait for the software in the period of time specified by the
* : argument.
* : Alter this function according to the user's system.
* Arguments : uint32_t msec ; Wait Time (msec)
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_delay_xms (uint32_t msec)
{
osDelay(msec);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_delay_10us
* Description : Waits for software for the period specified by the argument.
* : Alter this function according to the user's system.
* Arguments : uint32_t usec ; Wait Time(x 10usec)
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_delay_10us (uint32_t usec)
{
volatile int i;
/* Wait 10us (Please change for your MCU) */
for (i = 0; i < usec; ++i)
{
Userdef_USB_usb0_host_delay_10us_2();
}
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_delay_10us_2
* Description : Waits for software for the period specified by the argument.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
static void Userdef_USB_usb0_host_delay_10us_2 (void)
{
volatile int i;
volatile unsigned long tmp;
/* Wait 1us (Please change for your MCU) */
for (i = 0; i < 14; ++i)
{
tmp = DUMMY_ACCESS;
}
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_delay_500ns
* Description : Wait for software for 500ns.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_delay_500ns (void)
{
volatile int i;
volatile unsigned long tmp;
/* Wait 500ns (Please change for your MCU) */
/* Wait 500ns I clock 266MHz */
tmp = DUMMY_ACCESS;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_start_dma
* Description : Enables DMA transfer on the information specified by the argument.
* : Set DMAC register by this function to enable DMA transfer.
* : After executing this function, USB module is set to start DMA
* : transfer. DMA transfer should not wait for DMA transfer complete.
* Arguments : USB_HOST_DMA_t *dma : DMA parameter
* : typedef struct{
* : uint32_t fifo; FIFO for using
* : uint32_t buffer; Start address of transfer source/destination
* : uint32_t bytes; Transfer size(Byte)
* : uint32_t dir; Transfer direction(0:Buffer->FIFO, 1:FIFO->Buffer)
* : uint32_t size; DMA transfer size
* : } USB_HOST_DMA_t;
* : uint16_t dfacc ; 0 : cycle steal mode
* : 1 : 16byte continuous mode
* : 2 : 32byte continuous mode
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_start_dma (USB_HOST_DMA_t * dma, uint16_t dfacc)
{
uint32_t trncount;
uint32_t src;
uint32_t dst;
uint32_t size;
uint32_t dir;
#ifdef CACHE_WRITEBACK
uint32_t ptr;
#endif
trncount = dma->bytes;
dir = dma->dir;
if (dir == USB_HOST_FIFO2BUF)
{
/* DxFIFO determination */
dst = dma->buffer;
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB200.D1FIFO.UINT32);
}
size = dma->size;
if (size == 0)
{
src += 3; /* byte access */
}
else if (size == 1)
{
src += 2; /* short access */
}
else
{
/* Do Nothing */
}
#else
size = dma->size;
if (size == 2)
{
/* 32bit access */
if (dfacc == 2)
{
/* 32byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB200.D0FIFOB0);
}
else
{
src = (uint32_t)(&USB200.D1FIFOB0);
}
}
else if (dfacc == 1)
{
/* 16byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB200.D0FIFOB0);
}
else
{
src = (uint32_t)(&USB200.D1FIFOB0);
}
}
else
{
/* normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB200.D1FIFO.UINT32);
}
}
}
else if (size == 1)
{
/* 16bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB200.D1FIFO.UINT32);
}
src += 2; /* short access */
}
else
{
/* 8bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB200.D1FIFO.UINT32);
}
src += 3; /* byte access */
}
#endif
}
else
{
/* DxFIFO determination */
src = dma->buffer;
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB200.D1FIFO.UINT32);
}
size = dma->size;
if (size == 0)
{
dst += 3; /* byte access */
}
else if (size == 1)
{
dst += 2; /* short access */
}
else
{
/* Do Nothing */
}
#else
size = dma->size;
if (size == 2)
{
/* 32bit access */
if (dfacc == 2)
{
/* 32byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB200.D0FIFOB0);
}
else
{
dst = (uint32_t)(&USB200.D1FIFOB0);
}
}
else if (dfacc == 1)
{
/* 16byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB200.D0FIFOB0);
}
else
{
dst = (uint32_t)(&USB200.D1FIFOB0);
}
}
else
{
/* normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB200.D1FIFO.UINT32);
}
}
}
else if (size == 1)
{
/* 16bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB200.D1FIFO.UINT32);
}
dst += 2; /* short access */
}
else
{
/* 8bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB200.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB200.D1FIFO.UINT32);
}
dst += 3; /* byte access */
}
#endif
}
#ifdef CACHE_WRITEBACK
ptr = (uint32_t)dma->buffer;
if ((ptr & 0x20000000ul) == 0)
{
io_cwb((uint32_t)ptr,(uint32_t)(ptr)+trncount);
}
#endif
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
usb0_host_enable_dmac0(src, dst, trncount, size, dir, dma->fifo, dfacc);
}
else
{
usb0_host_enable_dmac1(src, dst, trncount, size, dir, dma->fifo, dfacc);
}
}
/*******************************************************************************
* Function Name: usb0_host_enable_dmac0
* Description : Enables DMA transfer on the information specified by the argument.
* Arguments : uint32_t src : src address
* : uint32_t dst : dst address
* : uint32_t count : transfer byte
* : uint32_t size : transfer size
* : uint32_t dir : direction
* : uint32_t fifo : FIFO(D0FIFO or D1FIFO)
* : uint16_t dfacc : 0 : normal access
* : : 1 : 16byte access
* : : 2 : 32byte access
* Return Value : none
*******************************************************************************/
static void usb0_host_enable_dmac0 (uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc)
{
dmac_transinfo_t trans_info;
uint32_t request_factor = 0;
int32_t ret;
/* ==== Variable setting for DMAC initialization ==== */
trans_info.src_addr = (uint32_t)src; /* Start address of transfer source */
trans_info.dst_addr = (uint32_t)dst; /* Start address of transfer destination */
trans_info.count = (uint32_t)count; /* Total byte count to be transferred */
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
#else
if (dfacc == 2)
{
/* 32byte access */
trans_info.src_size = DMAC_TRANS_SIZE_256; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_256; /* Transfer destination transfer size */
}
else if (dfacc == 1)
{
/* 16byte access */
trans_info.src_size = DMAC_TRANS_SIZE_128; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_128; /* Transfer destination transfer size */
}
else
{
/* normal access */
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
}
#endif
if (dir == USB_HOST_FIFO2BUF)
{
request_factor = DMAC_REQ_USB0_DMA0_RX; /* USB_0 channel 0 receive FIFO full */
trans_info.saddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer destination address */
}
else if (dir == USB_HOST_BUF2FIFO)
{
request_factor = DMAC_REQ_USB0_DMA0_TX; /* USB_0 channel 0 receive FIFO empty */
trans_info.saddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer destination address */
}
else
{
/* Do Nothing */
}
/* ==== DMAC initialization ==== */
usb0_host_DMAC1_PeriReqInit((const dmac_transinfo_t *)&trans_info,
DMAC_MODE_REGISTER,
DMAC_SAMPLE_SINGLE,
request_factor,
0); /* Don't care DMAC_REQ_REQD is setting in usb0_host_DMAC1_PeriReqInit() */
/* ==== DMAC startup ==== */
ret = usb0_host_DMAC1_Open(DMAC_REQ_MODE_PERI);
if (ret != 0)
{
// printf("DMAC1 Open error!!\n");
}
return;
}
/*******************************************************************************
* Function Name: usb0_host_enable_dmac1
* Description : Enables DMA transfer on the information specified by the argument.
* Arguments : uint32_t src : src address
* : uint32_t dst : dst address
* : uint32_t count : transfer byte
* : uint32_t size : transfer size
* : uint32_t dir : direction
* : uint32_t fifo : FIFO(D0FIFO or D1FIFO)
* : uint16_t dfacc : 0 : normal access
* : : 1 : 16byte access
* : : 2 : 32byte access
* Return Value : none
*******************************************************************************/
static void usb0_host_enable_dmac1 (uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc)
{
dmac_transinfo_t trans_info;
uint32_t request_factor = 0;
int32_t ret;
/* ==== Variable setting for DMAC initialization ==== */
trans_info.src_addr = (uint32_t)src; /* Start address of transfer source */
trans_info.dst_addr = (uint32_t)dst; /* Start address of transfer destination */
trans_info.count = (uint32_t)count; /* Total byte count to be transferred */
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
#else
if (dfacc == 2)
{
/* 32byte access */
trans_info.src_size = DMAC_TRANS_SIZE_256; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_256; /* Transfer destination transfer size */
}
else if (dfacc == 1)
{
/* 16byte access */
trans_info.src_size = DMAC_TRANS_SIZE_128; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_128; /* Transfer destination transfer size */
}
else
{
/* normal access */
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
}
#endif
if (dir == USB_HOST_FIFO2BUF)
{
request_factor =DMAC_REQ_USB0_DMA1_RX; /* USB_0 channel 0 receive FIFO full */
trans_info.saddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer destination address */
}
else if (dir == USB_HOST_BUF2FIFO)
{
request_factor =DMAC_REQ_USB0_DMA1_TX; /* USB_0 channel 0 receive FIFO empty */
trans_info.saddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer destination address */
}
else
{
/* Do Nothing */
}
/* ==== DMAC initialization ==== */
usb0_host_DMAC2_PeriReqInit((const dmac_transinfo_t *)&trans_info,
DMAC_MODE_REGISTER,
DMAC_SAMPLE_SINGLE,
request_factor,
0); /* Don't care DMAC_REQ_REQD is setting in usb0_host_DMAC2_PeriReqInit() */
/* ==== DMAC startup ==== */
ret = usb0_host_DMAC2_Open(DMAC_REQ_MODE_PERI);
if (ret != 0)
{
// printf("DMAC2 Open error!!\n");
}
return;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_stop_dma0
* Description : Disables DMA transfer.
* Arguments : none
* Return Value : uint32_t return Transfer Counter register(DMATCRn) value
* : regarding to the bus width.
* Notice : This function should be executed to DMAC executed at the time
* : of specification of D0_FIF0_DMA in dma->fifo.
*******************************************************************************/
uint32_t Userdef_USB_usb0_host_stop_dma0 (void)
{
uint32_t remain;
/* ==== DMAC release ==== */
usb0_host_DMAC1_Close(&remain);
return remain;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_stop_dma1
* Description : Disables DMA transfer.
* : This function should be executed to DMAC executed at the time
* : of specification of D1_FIF0_DMA in dma->fifo.
* Arguments : none
* Return Value : uint32_t return Transfer Counter register(DMATCRn) value
* : regarding to the bus width.
*******************************************************************************/
uint32_t Userdef_USB_usb0_host_stop_dma1 (void)
{
uint32_t remain;
/* ==== DMAC release ==== */
usb0_host_DMAC2_Close(&remain);
return remain;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_notice
* Description : Notice of USER
* Arguments : const char *format
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_notice (const char * format)
{
// printf(format);
return;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb0_host_user_rdy
* Description : This function notify a user and wait for trigger
* Arguments : const char *format
* : uint16_t data
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb0_host_user_rdy (const char * format, uint16_t data)
{
// printf(format, data);
getchar();
return;
}
/* End of File */

View file

@ -0,0 +1,156 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB1_HOST_H
#define USB1_HOST_H
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "devdrv_usb_host_api.h"
#include "usb_host.h"
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
extern const uint16_t g_usb1_host_bit_set[];
extern uint32_t g_usb1_host_data_count[USB_HOST_MAX_PIPE_NO + 1];
extern uint8_t *g_usb1_host_data_pointer[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb1_host_PipeIgnore[];
extern uint16_t g_usb1_host_PipeTbl[];
extern uint16_t g_usb1_host_pipe_status[];
extern uint32_t g_usb1_host_PipeDataSize[];
extern USB_HOST_DMA_t g_usb1_host_DmaInfo[];
extern uint16_t g_usb1_host_DmaPipe[];
extern uint16_t g_usb1_host_DmaBval[];
extern uint16_t g_usb1_host_DmaStatus[];
extern uint16_t g_usb1_host_driver_state;
extern uint16_t g_usb1_host_ConfigNum;
extern uint16_t g_usb1_host_CmdStage;
extern uint16_t g_usb1_host_bchg_flag;
extern uint16_t g_usb1_host_detach_flag;
extern uint16_t g_usb1_host_attach_flag;
extern uint16_t g_usb1_host_UsbAddress;
extern uint16_t g_usb1_host_setUsbAddress;
extern uint16_t g_usb1_host_default_max_packet[USB_HOST_MAX_DEVICE + 1];
extern uint16_t g_usb1_host_UsbDeviceSpeed;
extern uint16_t g_usb1_host_SupportUsbDeviceSpeed;
extern uint16_t g_usb1_host_SavReq;
extern uint16_t g_usb1_host_SavVal;
extern uint16_t g_usb1_host_SavIndx;
extern uint16_t g_usb1_host_SavLen;
extern uint16_t g_usb1_host_pipecfg[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb1_host_pipebuf[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb1_host_pipemaxp[USB_HOST_MAX_PIPE_NO + 1];
extern uint16_t g_usb1_host_pipeperi[USB_HOST_MAX_PIPE_NO + 1];
/*******************************************************************************
Functions Prototypes
*******************************************************************************/
/* ==== common ==== */
void usb1_host_dma_stop_d0(uint16_t pipe, uint32_t remain);
void usb1_host_dma_stop_d1(uint16_t pipe, uint32_t remain);
uint16_t usb1_host_is_hispeed(void);
uint16_t usb1_host_is_hispeed_enable(void);
uint16_t usb1_host_start_send_transfer(uint16_t pipe, uint32_t size, uint8_t *data);
uint16_t usb1_host_write_buffer(uint16_t pipe);
uint16_t usb1_host_write_buffer_c(uint16_t pipe);
uint16_t usb1_host_write_buffer_d0(uint16_t pipe);
uint16_t usb1_host_write_buffer_d1(uint16_t pipe);
void usb1_host_start_receive_transfer(uint16_t pipe, uint32_t size, uint8_t *data);
uint16_t usb1_host_read_buffer(uint16_t pipe);
uint16_t usb1_host_read_buffer_c(uint16_t pipe);
uint16_t usb1_host_read_buffer_d0(uint16_t pipe);
uint16_t usb1_host_read_buffer_d1(uint16_t pipe);
uint16_t usb1_host_change_fifo_port(uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw);
void usb1_host_set_curpipe(uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw);
void usb1_host_set_curpipe2(uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw, uint16_t dfacc);
uint16_t usb1_host_get_mbw(uint32_t trncount, uint32_t dtptr);
uint16_t usb1_host_read_dma(uint16_t pipe);
void usb1_host_stop_transfer(uint16_t pipe);
void usb1_host_brdy_int(uint16_t status, uint16_t int_enb);
void usb1_host_nrdy_int(uint16_t status, uint16_t int_enb);
void usb1_host_bemp_int(uint16_t status, uint16_t int_enb);
void usb1_host_setting_interrupt(uint8_t level);
void usb1_host_reset_module(uint16_t clockmode);
uint16_t usb1_host_get_buf_size(uint16_t pipe);
uint16_t usb1_host_get_mxps(uint16_t pipe);
void usb1_host_enable_brdy_int(uint16_t pipe);
void usb1_host_disable_brdy_int(uint16_t pipe);
void usb1_host_clear_brdy_sts(uint16_t pipe);
void usb1_host_enable_bemp_int(uint16_t pipe);
void usb1_host_disable_bemp_int(uint16_t pipe);
void usb1_host_clear_bemp_sts(uint16_t pipe);
void usb1_host_enable_nrdy_int(uint16_t pipe);
void usb1_host_disable_nrdy_int(uint16_t pipe);
void usb1_host_clear_nrdy_sts(uint16_t pipe);
void usb1_host_set_pid_buf(uint16_t pipe);
void usb1_host_set_pid_nak(uint16_t pipe);
void usb1_host_set_pid_stall(uint16_t pipe);
void usb1_host_clear_pid_stall(uint16_t pipe);
uint16_t usb1_host_get_pid(uint16_t pipe);
void usb1_host_set_sqclr(uint16_t pipe);
void usb1_host_set_sqset(uint16_t pipe);
void usb1_host_set_csclr(uint16_t pipe);
void usb1_host_aclrm(uint16_t pipe);
void usb1_host_set_aclrm(uint16_t pipe);
void usb1_host_clr_aclrm(uint16_t pipe);
uint16_t usb1_host_get_sqmon(uint16_t pipe);
uint16_t usb1_host_get_inbuf(uint16_t pipe);
/* ==== host ==== */
void usb1_host_init_pipe_status(void);
int32_t usb1_host_CtrlTransStart(uint16_t devadr, uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len, uint8_t *Buf);
void usb1_host_SetupStage(uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len);
void usb1_host_CtrlReadStart(uint32_t Bsize, uint8_t *Table);
uint16_t usb1_host_CtrlWriteStart(uint32_t Bsize, uint8_t *Table);
void usb1_host_StatusStage(void);
void usb1_host_get_devadd(uint16_t addr, uint16_t *devadd);
void usb1_host_set_devadd(uint16_t addr, uint16_t *devadd);
void usb1_host_InitModule(void);
uint16_t usb1_host_CheckAttach(void);
void usb1_host_UsbDetach(void);
void usb1_host_UsbDetach2(void);
void usb1_host_UsbAttach(void);
uint16_t usb1_host_UsbBusReset(void);
int32_t usb1_host_UsbResume(void);
int32_t usb1_host_UsbSuspend(void);
void usb1_host_Enable_DetachINT(void);
void usb1_host_Disable_DetachINT(void);
void usb1_host_UsbStateManager(void);
#endif /* USB1_HOST_H */
/* End of File */

View file

@ -0,0 +1,112 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_api.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB1_HOST_API_H
#define USB1_HOST_API_H
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Variable Externs
*******************************************************************************/
/*******************************************************************************
Functions Prototypes
*******************************************************************************/
void usb1_host_interrupt(uint32_t int_sense);
void usb1_host_dma_interrupt_d0fifo(uint32_t int_sense);
void usb1_host_dma_interrupt_d1fifo(uint32_t int_sense);
uint16_t usb1_api_host_init(uint8_t int_level, uint16_t mode, uint16_t clockmode);
int32_t usb1_api_host_enumeration(uint16_t devadr);
int32_t usb1_api_host_detach(void);
int32_t usb1_api_host_data_in(uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t *data_buf);
int32_t usb1_api_host_data_out(uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t *data_buf);
int32_t usb1_api_host_control_transfer(uint16_t devadr, uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len, uint8_t *Buf);
int32_t usb1_api_host_set_endpoint(uint16_t devadr, USB_HOST_CFG_PIPETBL_t *user_table, uint8_t *configdescriptor);
int32_t usb1_api_host_clear_endpoint(USB_HOST_CFG_PIPETBL_t *user_table);
int32_t usb1_api_host_clear_endpoint_pipe(uint16_t pipe_sel, USB_HOST_CFG_PIPETBL_t *user_table);
uint16_t usb1_api_host_SetEndpointTable(uint16_t devadr, USB_HOST_CFG_PIPETBL_t *user_table, uint8_t *Table);
int32_t usb1_api_host_data_count(uint16_t pipe, uint32_t *data_count);
int32_t usb1_api_host_GetDeviceDescriptor(uint16_t devadr, uint16_t size, uint8_t *buf);
int32_t usb1_api_host_GetConfigDescriptor(uint16_t devadr, uint16_t size, uint8_t *buf);
int32_t usb1_api_host_SetConfig(uint16_t devadr, uint16_t confignum);
int32_t usb1_api_host_SetInterface(uint16_t devadr, uint16_t interface_alt, uint16_t interface_index);
int32_t usb1_api_host_ClearStall(uint16_t devadr, uint16_t ep_dir);
uint16_t usb1_api_host_GetUsbDeviceState(void);
void usb1_api_host_elt_4_4(void);
void usb1_api_host_elt_4_5(void);
void usb1_api_host_elt_4_6(void);
void usb1_api_host_elt_4_7(void);
void usb1_api_host_elt_4_8(void);
void usb1_api_host_elt_4_9(void);
void usb1_api_host_elt_get_desc(void);
void usb1_host_EL_ModeInit(void);
void usb1_host_EL_SetUACT(void);
void usb1_host_EL_ClearUACT(void);
void usb1_host_EL_SetTESTMODE(uint16_t mode);
void usb1_host_EL_ClearNRDYSTS(uint16_t pipe);
uint16_t usb1_host_EL_GetINTSTS1(void);
void usb1_host_EL_UsbBusReset(void);
void usb1_host_EL_UsbAttach(void);
void usb1_host_EL_SetupStage(uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len);
void usb1_host_EL_StatusStage(void);
void usb1_host_EL_CtrlReadStart(uint32_t Bsize, uint8_t *Table);
int32_t usb1_host_EL_UsbSuspend(void);
int32_t usb1_host_EL_UsbResume(void);
#if 0 /* prototype in devdrv_usb_host_api.h */
uint16_t Userdef_USB_usb1_host_d0fifo_dmaintid(void);
uint16_t Userdef_USB_usb1_host_d1fifo_dmaintid(void);
void Userdef_USB_usb1_host_attach(void);
void Userdef_USB_usb1_host_detach(void);
void Userdef_USB_usb1_host_delay_1ms(void);
void Userdef_USB_usb1_host_delay_xms(uint32_t msec);
void Userdef_USB_usb1_host_delay_10us(uint32_t usec);
void Userdef_USB_usb1_host_delay_500ns(void);
void Userdef_USB_usb1_host_start_dma(USB_HOST_DMA_t *dma, uint16_t dfacc);
uint32_t Userdef_USB_usb1_host_stop_dma0(void);
uint32_t Userdef_USB_usb1_host_stop_dma1(void);
#endif
#endif /* USB1_HOST_API_H */
/* End of File */

View file

@ -0,0 +1,139 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_dmacdrv.h
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Description : RZ/A1H R7S72100 USB Sample Program
*******************************************************************************/
#ifndef USB1_HOST_DMACDRV_H
#define USB1_HOST_DMACDRV_H
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
/*******************************************************************************
Typedef definitions
*******************************************************************************/
typedef struct dmac_transinfo
{
uint32_t src_addr; /* Transfer source address */
uint32_t dst_addr; /* Transfer destination address */
uint32_t count; /* Transfer byte count */
uint32_t src_size; /* Transfer source data size */
uint32_t dst_size; /* Transfer destination data size */
uint32_t saddr_dir; /* Transfer source address direction */
uint32_t daddr_dir; /* Transfer destination address direction */
} dmac_transinfo_t;
/*******************************************************************************
Macro definitions
*******************************************************************************/
/* ==== Transfer specification of the sample program ==== */
#define DMAC_SAMPLE_SINGLE (0) /* Single transfer */
#define DMAC_SAMPLE_CONTINUATION (1) /* Continuous transfer (use REN bit) */
/* ==== DMA modes ==== */
#define DMAC_MODE_REGISTER (0) /* Register mode */
#define DMAC_MODE_LINK (1) /* Link mode */
/* ==== Transfer requests ==== */
#define DMAC_REQ_MODE_EXT (0) /* External request */
#define DMAC_REQ_MODE_PERI (1) /* On-chip peripheral module request */
#define DMAC_REQ_MODE_SOFT (2) /* Auto-request (request by software) */
/* ==== DMAC transfer sizes ==== */
#define DMAC_TRANS_SIZE_8 (0) /* 8 bits */
#define DMAC_TRANS_SIZE_16 (1) /* 16 bits */
#define DMAC_TRANS_SIZE_32 (2) /* 32 bits */
#define DMAC_TRANS_SIZE_64 (3) /* 64 bits */
#define DMAC_TRANS_SIZE_128 (4) /* 128 bits */
#define DMAC_TRANS_SIZE_256 (5) /* 256 bits */
#define DMAC_TRANS_SIZE_512 (6) /* 512 bits */
#define DMAC_TRANS_SIZE_1024 (7) /* 1024 bits */
/* ==== Address increment for transferring ==== */
#define DMAC_TRANS_ADR_NO_INC (1) /* Not increment */
#define DMAC_TRANS_ADR_INC (0) /* Increment */
/* ==== Method for detecting DMA request ==== */
#define DMAC_REQ_DET_FALL (0) /* Falling edge detection */
#define DMAC_REQ_DET_RISE (1) /* Rising edge detection */
#define DMAC_REQ_DET_LOW (2) /* Low level detection */
#define DMAC_REQ_DET_HIGH (3) /* High level detection */
/* ==== Request Direction ==== */
#define DMAC_REQ_DIR_SRC (0) /* DMAREQ is the source/ DMAACK is active when reading */
#define DMAC_REQ_DIR_DST (1) /* DMAREQ is the destination/ DMAACK is active when writing */
/* ==== Descriptors ==== */
#define DMAC_DESC_HEADER (0) /* Header */
#define DMAC_DESC_SRC_ADDR (1) /* Source Address */
#define DMAC_DESC_DST_ADDR (2) /* Destination Address */
#define DMAC_DESC_COUNT (3) /* Transaction Byte */
#define DMAC_DESC_CHCFG (4) /* Channel Confg */
#define DMAC_DESC_CHITVL (5) /* Channel Interval */
#define DMAC_DESC_CHEXT (6) /* Channel Extension */
#define DMAC_DESC_LINK_ADDR (7) /* Link Address */
/* ==== On-chip peripheral module requests ===== */
typedef enum dmac_request_factor
{
DMAC_REQ_USB0_DMA0_TX, /* USB_0 channel 0 transmit FIFO empty */
DMAC_REQ_USB0_DMA0_RX, /* USB_0 channel 0 receive FIFO full */
DMAC_REQ_USB0_DMA1_TX, /* USB_0 channel 1 transmit FIFO empty */
DMAC_REQ_USB0_DMA1_RX, /* USB_0 channel 1 receive FIFO full */
DMAC_REQ_USB1_DMA0_TX, /* USB_1 channel 0 transmit FIFO empty */
DMAC_REQ_USB1_DMA0_RX, /* USB_1 channel 0 receive FIFO full */
DMAC_REQ_USB1_DMA1_TX, /* USB_1 channel 1 transmit FIFO empty */
DMAC_REQ_USB1_DMA1_RX, /* USB_1 channel 1 receive FIFO full */
} dmac_request_factor_t;
/*******************************************************************************
Variable Externs
*******************************************************************************/
/*******************************************************************************
Functions Prototypes
*******************************************************************************/
void usb1_host_DMAC3_PeriReqInit(const dmac_transinfo_t *trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction);
int32_t usb1_host_DMAC3_Open(uint32_t req);
void usb1_host_DMAC3_Close(uint32_t *remain);
void usb1_host_DMAC3_Load_Set(uint32_t src_addr, uint32_t dst_addr, uint32_t count);
void usb1_host_DMAC4_PeriReqInit(const dmac_transinfo_t *trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction);
int32_t usb1_host_DMAC4_Open(uint32_t req);
void usb1_host_DMAC4_Close(uint32_t *remain);
void usb1_host_DMAC4_Load_Set(uint32_t src_addr, uint32_t dst_addr, uint32_t count);
#endif /* USB1_HOST_DMACDRV_H */
/* End of File */

View file

@ -0,0 +1,355 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_dma.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb1_host.h"
/* #include "usb1_host_dmacdrv.h" */
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
static void usb1_host_dmaint(uint16_t fifo);
static void usb1_host_dmaint_buf2fifo(uint16_t pipe);
static void usb1_host_dmaint_fifo2buf(uint16_t pipe);
/*******************************************************************************
* Function Name: usb1_host_dma_stop_d0
* Description : D0FIFO DMA stop
* Arguments : uint16_t pipe : pipe number
* : uint32_t remain : transfer byte
* Return Value : none
*******************************************************************************/
void usb1_host_dma_stop_d0 (uint16_t pipe, uint32_t remain)
{
uint16_t dtln;
uint16_t dfacc;
uint16_t buffer;
uint16_t sds_b = 1;
dfacc = RZA_IO_RegRead_16(&USB201.D0FBCFG,
USB_DnFBCFG_DFACC_SHIFT,
USB_DnFBCFG_DFACC);
if (dfacc == 2)
{
sds_b = 32;
}
else if (dfacc == 1)
{
sds_b = 16;
}
else
{
if (g_usb1_host_DmaInfo[USB_HOST_D0FIFO].size == 2)
{
sds_b = 4;
}
else if (g_usb1_host_DmaInfo[USB_HOST_D0FIFO].size == 1)
{
sds_b = 2;
}
else
{
sds_b = 1;
}
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
{
if (g_usb1_host_pipe_status[pipe] != USB_HOST_PIPE_DONE)
{
buffer = USB201.D0FIFOCTR;
dtln = (buffer & USB_HOST_BITDTLN);
if ((dtln % sds_b) != 0)
{
remain += (sds_b - (dtln % sds_b));
}
g_usb1_host_PipeDataSize[pipe] = (g_usb1_host_data_count[pipe] - remain);
g_usb1_host_data_count[pipe] = remain;
}
}
RZA_IO_RegWrite_16(&USB201.D0FIFOSEL,
0,
USB_DnFIFOSEL_DREQE_SHIFT,
USB_DnFIFOSEL_DREQE);
}
/*******************************************************************************
* Function Name: usb1_host_dma_stop_d1
* Description : D1FIFO DMA stop
* Arguments : uint16_t pipe : pipe number
* : uint32_t remain : transfer byte
* Return Value : none
*******************************************************************************/
void usb1_host_dma_stop_d1 (uint16_t pipe, uint32_t remain)
{
uint16_t dtln;
uint16_t dfacc;
uint16_t buffer;
uint16_t sds_b = 1;
dfacc = RZA_IO_RegRead_16(&USB201.D1FBCFG,
USB_DnFBCFG_DFACC_SHIFT,
USB_DnFBCFG_DFACC);
if (dfacc == 2)
{
sds_b = 32;
}
else if (dfacc == 1)
{
sds_b = 16;
}
else
{
if (g_usb1_host_DmaInfo[USB_HOST_D1FIFO].size == 2)
{
sds_b = 4;
}
else if (g_usb1_host_DmaInfo[USB_HOST_D1FIFO].size == 1)
{
sds_b = 2;
}
else
{
sds_b = 1;
}
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
{
if (g_usb1_host_pipe_status[pipe] != USB_HOST_PIPE_DONE)
{
buffer = USB201.D1FIFOCTR;
dtln = (buffer & USB_HOST_BITDTLN);
if ((dtln % sds_b) != 0)
{
remain += (sds_b - (dtln % sds_b));
}
g_usb1_host_PipeDataSize[pipe] = (g_usb1_host_data_count[pipe] - remain);
g_usb1_host_data_count[pipe] = remain;
}
}
RZA_IO_RegWrite_16(&USB201.D1FIFOSEL,
0,
USB_DnFIFOSEL_DREQE_SHIFT,
USB_DnFIFOSEL_DREQE);
}
/*******************************************************************************
* Function Name: usb1_host_dma_interrupt_d0fifo
* Description : This function is DMA interrupt handler entry.
* : Execute usb1_host_dmaint() after disabling DMA interrupt in this function.
* : Disable DMA interrupt to DMAC executed when USB_HOST_D0FIFO_DMA is
* : specified by dma->fifo.
* : Register this function as DMA complete interrupt.
* Arguments : uint32_t int_sense ; Interrupts detection mode
* : ; INTC_LEVEL_SENSITIVE : Level sense
* : ; INTC_EDGE_TRIGGER : Edge trigger
* Return Value : none
*******************************************************************************/
void usb1_host_dma_interrupt_d0fifo (uint32_t int_sense)
{
usb1_host_dmaint(USB_HOST_D0FIFO);
g_usb1_host_DmaStatus[USB_HOST_D0FIFO] = USB_HOST_DMA_READY;
}
/*******************************************************************************
* Function Name: usb1_host_dma_interrupt_d1fifo
* Description : This function is DMA interrupt handler entry.
* : Execute usb0_host_dmaint() after disabling DMA interrupt in this function.
* : Disable DMA interrupt to DMAC executed when USB_HOST_D1FIFO_DMA is
* : specified by dma->fifo.
* : Register this function as DMA complete interrupt.
* Arguments : uint32_t int_sense ; Interrupts detection mode
* : ; INTC_LEVEL_SENSITIVE : Level sense
* : ; INTC_EDGE_TRIGGER : Edge trigger
* Return Value : none
*******************************************************************************/
void usb1_host_dma_interrupt_d1fifo (uint32_t int_sense)
{
usb1_host_dmaint(USB_HOST_D1FIFO);
g_usb1_host_DmaStatus[USB_HOST_D1FIFO] = USB_HOST_DMA_READY;
}
/*******************************************************************************
* Function Name: usb1_host_dmaint
* Description : This function is DMA transfer end interrupt
* Arguments : uint16_t fifo ; fifo number
* : ; USB_HOST_D0FIFO
* : ; USB_HOST_D1FIFO
* Return Value : none
*******************************************************************************/
static void usb1_host_dmaint (uint16_t fifo)
{
uint16_t pipe;
pipe = g_usb1_host_DmaPipe[fifo];
if (g_usb1_host_DmaInfo[fifo].dir == USB_HOST_BUF2FIFO)
{
usb1_host_dmaint_buf2fifo(pipe);
}
else
{
usb1_host_dmaint_fifo2buf(pipe);
}
}
/*******************************************************************************
* Function Name: usb1_host_dmaint_fifo2buf
* Description : Executes read completion from FIFO by DMAC.
* Arguments : uint16_t pipe : pipe number
* Return Value : none
*******************************************************************************/
static void usb1_host_dmaint_fifo2buf (uint16_t pipe)
{
uint32_t remain;
uint16_t useport;
if (g_usb1_host_pipe_status[pipe] != USB_HOST_PIPE_DONE)
{
useport = (uint16_t)(g_usb1_host_PipeTbl[pipe] & USB_HOST_FIFO_USE);
if (useport == USB_HOST_D0FIFO_DMA)
{
remain = Userdef_USB_usb1_host_stop_dma0();
usb1_host_dma_stop_d0(pipe, remain);
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
if (g_usb1_host_DmaStatus[USB_HOST_D0FIFO] == USB_HOST_DMA_BUSYEND)
{
USB201.D0FIFOCTR = USB_HOST_BITBCLR;
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
else
{
usb1_host_enable_brdy_int(pipe);
}
}
}
else
{
remain = Userdef_USB_usb1_host_stop_dma1();
usb1_host_dma_stop_d1(pipe, remain);
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
if (g_usb1_host_DmaStatus[USB_HOST_D1FIFO] == USB_HOST_DMA_BUSYEND)
{
USB201.D1FIFOCTR = USB_HOST_BITBCLR;
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
else
{
usb1_host_enable_brdy_int(pipe);
}
}
}
}
}
/*******************************************************************************
* Function Name: usb1_host_dmaint_buf2fifo
* Description : Executes write completion in FIFO by DMAC.
* Arguments : uint16_t pipe : pipe number
* Return Value : none
*******************************************************************************/
static void usb1_host_dmaint_buf2fifo (uint16_t pipe)
{
uint16_t useport;
uint32_t remain;
useport = (uint16_t)(g_usb1_host_PipeTbl[pipe] & USB_HOST_FIFO_USE);
if (useport == USB_HOST_D0FIFO_DMA)
{
remain = Userdef_USB_usb1_host_stop_dma0();
usb1_host_dma_stop_d0(pipe, remain);
if (g_usb1_host_DmaBval[USB_HOST_D0FIFO] != 0)
{
RZA_IO_RegWrite_16(&USB201.D0FIFOCTR,
1,
USB_DnFIFOCTR_BVAL_SHIFT,
USB_DnFIFOCTR_BVAL);
}
}
else
{
remain = Userdef_USB_usb1_host_stop_dma1();
usb1_host_dma_stop_d1(pipe, remain);
if (g_usb1_host_DmaBval[USB_HOST_D1FIFO] != 0)
{
RZA_IO_RegWrite_16(&USB201.D1FIFOCTR,
1,
USB_DnFIFOCTR_BVAL_SHIFT,
USB_DnFIFOCTR_BVAL);
}
}
usb1_host_enable_bemp_int(pipe);
}
/* End of File */

View file

@ -0,0 +1,285 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_intrn.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb1_host.h"
#if(1) /* ohci_wrapp */
#include "ohci_wrapp_RZ_A1_local.h"
#endif
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb1_host_brdy_int
* Description : Executes BRDY interrupt(USB_HOST_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_enb ; BRDYENB Register Value
* Return Value : none
*******************************************************************************/
void usb1_host_brdy_int (uint16_t status, uint16_t int_enb)
{
uint32_t int_sense = 0;
uint16_t pipe;
uint16_t pipebit;
for (pipe = USB_HOST_PIPE1; pipe <= USB_HOST_MAX_PIPE_NO; pipe++)
{
pipebit = g_usb1_host_bit_set[pipe];
if ((status & pipebit) && (int_enb & pipebit))
{
USB201.BRDYSTS = (uint16_t)~pipebit;
USB201.BEMPSTS = (uint16_t)~pipebit;
if ((g_usb1_host_PipeTbl[pipe] & USB_HOST_FIFO_USE) == USB_HOST_D0FIFO_DMA)
{
if (g_usb1_host_DmaStatus[USB_HOST_D0FIFO] != USB_HOST_DMA_READY)
{
usb1_host_dma_interrupt_d0fifo(int_sense);
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
usb1_host_read_dma(pipe);
usb1_host_disable_brdy_int(pipe);
}
else
{
USB201.D0FIFOCTR = USB_HOST_BITBCLR;
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
}
else if ((g_usb1_host_PipeTbl[pipe] & USB_HOST_FIFO_USE) == USB_HOST_D1FIFO_DMA)
{
if (g_usb1_host_DmaStatus[USB_HOST_D1FIFO] != USB_HOST_DMA_READY)
{
usb1_host_dma_interrupt_d1fifo(int_sense);
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
{
usb1_host_read_dma(pipe);
usb1_host_disable_brdy_int(pipe);
}
else
{
USB201.D1FIFOCTR = USB_HOST_BITBCLR;
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
}
}
else
{
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0)
{
usb1_host_read_buffer(pipe);
}
else
{
usb1_host_write_buffer(pipe);
}
}
#if(1) /* ohci_wrapp */
switch (g_usb1_host_pipe_status[pipe])
{
case USB_HOST_PIPE_DONE:
ohciwrapp_loc_TransEnd(pipe, TD_CC_NOERROR);
break;
case USB_HOST_PIPE_NORES:
case USB_HOST_PIPE_STALL:
case USB_HOST_PIPE_ERROR:
ohciwrapp_loc_TransEnd(pipe, TD_CC_STALL);
break;
default:
/* Do Nothing */
break;
}
#endif
}
}
}
/*******************************************************************************
* Function Name: usb1_host_nrdy_int
* Description : Executes NRDY interrupt(USB_HOST_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 USB_HOST_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
*******************************************************************************/
void usb1_host_nrdy_int (uint16_t status, uint16_t int_enb)
{
uint16_t pid;
uint16_t pipe;
uint16_t bitcheck;
bitcheck = (uint16_t)(status & int_enb);
USB201.NRDYSTS = (uint16_t)~status;
for (pipe = USB_HOST_PIPE1; pipe <= USB_HOST_MAX_PIPE_NO; pipe++)
{
if ((bitcheck&g_usb1_host_bit_set[pipe]) == g_usb1_host_bit_set[pipe])
{
if (RZA_IO_RegRead_16(&USB201.SYSCFG0,
USB_SYSCFG_DCFM_SHIFT,
USB_SYSCFG_DCFM) == 1)
{
if (g_usb1_host_pipe_status[pipe] == USB_HOST_PIPE_WAIT)
{
pid = usb1_host_get_pid(pipe);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_STALL;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(pipe, TD_CC_STALL);
#endif
}
else
{
#if(1) /* ohci_wrapp */
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_NORES;
ohciwrapp_loc_TransEnd(pipe, TD_CC_DEVICENOTRESPONDING);
#else
g_usb1_host_PipeIgnore[pipe]++;
if (g_usb1_host_PipeIgnore[pipe] == 3)
{
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_NORES;
}
else
{
usb1_host_set_pid_buf(pipe);
}
#endif
}
}
}
else
{
/* USB Function */
}
}
}
}
/*******************************************************************************
* Function Name: usb1_host_bemp_int
* Description : Executes BEMP interrupt(USB_HOST_PIPE1-9).
* Arguments : uint16_t status ; BEMPSTS Register Value
* : uint16_t int_enb ; BEMPENB Register Value
* Return Value : none
*******************************************************************************/
void usb1_host_bemp_int (uint16_t status, uint16_t int_enb)
{
uint16_t pid;
uint16_t pipe;
uint16_t bitcheck;
uint16_t inbuf;
bitcheck = (uint16_t)(status & int_enb);
USB201.BEMPSTS = (uint16_t)~status;
for (pipe = USB_HOST_PIPE1; pipe <= USB_HOST_MAX_PIPE_NO; pipe++)
{
if ((bitcheck&g_usb1_host_bit_set[pipe]) == g_usb1_host_bit_set[pipe])
{
pid = usb1_host_get_pid(pipe);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_STALL;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(pipe, TD_CC_STALL);
#endif
}
else
{
inbuf = usb1_host_get_inbuf(pipe);
if (inbuf == 0)
{
usb1_host_disable_bemp_int(pipe);
usb1_host_set_pid_nak(pipe);
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_DONE;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(pipe, TD_CC_NOERROR);
#endif
}
}
}
}
}
/* End of File */

View file

@ -0,0 +1,434 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_controlrw.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb1_host.h"
#include "dev_drv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb1_host_CtrlTransStart
* Description : Executes USB control transfer.
* Arguments : uint16_t devadr ; device address
* : uint16_t Req ; bmRequestType & bRequest
* : uint16_t Val ; wValue
* : uint16_t Indx ; wIndex
* : uint16_t Len ; wLength
* : uint8_t *Buf ; Data buffer
* Return Value : DEVDRV_SUCCESS ; SUCCESS
* : DEVDRV_ERROR ; ERROR
*******************************************************************************/
int32_t usb1_host_CtrlTransStart (uint16_t devadr, uint16_t Req, uint16_t Val,
uint16_t Indx, uint16_t Len, uint8_t * Buf)
{
if (g_usb1_host_UsbDeviceSpeed == USB_HOST_LOW_SPEED)
{
RZA_IO_RegWrite_16(&USB201.SOFCFG,
1,
USB_SOFCFG_TRNENSEL_SHIFT,
USB_SOFCFG_TRNENSEL);
}
else
{
RZA_IO_RegWrite_16(&USB201.SOFCFG,
0,
USB_SOFCFG_TRNENSEL_SHIFT,
USB_SOFCFG_TRNENSEL);
}
USB201.DCPMAXP = (uint16_t)((uint16_t)(devadr << 12) + g_usb1_host_default_max_packet[devadr]);
if (g_usb1_host_pipe_status[USB_HOST_PIPE0] == USB_HOST_PIPE_IDLE)
{
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_WAIT;
g_usb1_host_PipeIgnore[USB_HOST_PIPE0] = 0; /* Ignore count clear */
g_usb1_host_CmdStage = (USB_HOST_STAGE_SETUP | USB_HOST_CMD_IDLE);
if (Len == 0)
{
g_usb1_host_CmdStage |= USB_HOST_MODE_NO_DATA; /* No-data Control */
}
else
{
if ((Req & 0x0080) != 0)
{
g_usb1_host_CmdStage |= USB_HOST_MODE_READ; /* Control Read */
}
else
{
g_usb1_host_CmdStage |= USB_HOST_MODE_WRITE; /* Control Write */
}
}
g_usb1_host_SavReq = Req; /* save request */
g_usb1_host_SavVal = Val;
g_usb1_host_SavIndx = Indx;
g_usb1_host_SavLen = Len;
}
else
{
if ((g_usb1_host_SavReq != Req) || (g_usb1_host_SavVal != Val)
|| (g_usb1_host_SavIndx != Indx) || (g_usb1_host_SavLen != Len))
{
return DEVDRV_ERROR;
}
}
switch ((g_usb1_host_CmdStage & (USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
/* --------------- SETUP STAGE --------------- */
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_IDLE):
usb1_host_SetupStage(Req, Val, Indx, Len);
break;
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_DOING):
/* do nothing */
break;
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_DONE): /* goto next stage */
g_usb1_host_PipeIgnore[USB_HOST_PIPE0] = 0; /* Ignore count clear */
switch ((g_usb1_host_CmdStage & (USB_HOST_MODE_FIELD)))
{
case USB_HOST_MODE_WRITE:
g_usb1_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb1_host_CmdStage |= USB_HOST_STAGE_DATA;
break;
case USB_HOST_MODE_READ:
g_usb1_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb1_host_CmdStage |= USB_HOST_STAGE_DATA;
break;
case USB_HOST_MODE_NO_DATA:
g_usb1_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb1_host_CmdStage |= USB_HOST_STAGE_STATUS;
break;
default:
break;
}
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_IDLE;
break;
case (USB_HOST_STAGE_SETUP | USB_HOST_CMD_NORES):
if (g_usb1_host_PipeIgnore[USB_HOST_PIPE0] == 3)
{
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
}
else
{
g_usb1_host_PipeIgnore[USB_HOST_PIPE0]++; /* Ignore count */
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_IDLE;
}
break;
/* --------------- DATA STAGE --------------- */
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_IDLE):
switch ((g_usb1_host_CmdStage & (USB_HOST_MODE_FIELD)))
{
case USB_HOST_MODE_WRITE:
usb1_host_CtrlWriteStart((uint32_t)Len, Buf);
break;
case USB_HOST_MODE_READ:
usb1_host_CtrlReadStart((uint32_t)Len, Buf);
break;
default:
break;
}
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
/* do nothing */
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DONE): /* goto next stage */
g_usb1_host_PipeIgnore[USB_HOST_PIPE0] = 0; /* Ignore count clear */
g_usb1_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb1_host_CmdStage |= USB_HOST_STAGE_STATUS;
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_IDLE;
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_NORES):
if (g_usb1_host_PipeIgnore[USB_HOST_PIPE0] == 3)
{
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
}
else
{
g_usb1_host_PipeIgnore[USB_HOST_PIPE0]++; /* Ignore count */
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DOING;
usb1_host_clear_pid_stall(USB_HOST_PIPE0);
usb1_host_set_pid_buf(USB_HOST_PIPE0);
}
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_STALL):
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL; /* exit STALL */
break;
/* --------------- STATUS STAGE --------------- */
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_IDLE):
usb1_host_StatusStage();
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
/* do nothing */
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DONE): /* end of Control transfer */
usb1_host_set_pid_nak(USB_HOST_PIPE0);
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_DONE; /* exit DONE */
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_NORES):
if (g_usb1_host_PipeIgnore[USB_HOST_PIPE0] == 3)
{
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
}
else
{
g_usb1_host_PipeIgnore[USB_HOST_PIPE0]++; /* Ignore count */
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DOING;
usb1_host_clear_pid_stall(USB_HOST_PIPE0);
usb1_host_set_pid_buf(USB_HOST_PIPE0);
}
break;
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_STALL):
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL; /* exit STALL */
break;
default:
break;
}
if (g_usb1_host_pipe_status[USB_HOST_PIPE0] != USB_HOST_PIPE_WAIT)
{
RZA_IO_RegWrite_16(&USB201.SOFCFG,
0,
USB_SOFCFG_TRNENSEL_SHIFT,
USB_SOFCFG_TRNENSEL);
}
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb1_host_SetupStage
* Description : Executes USB control transfer/set up stage.
* Arguments : uint16_t Req ; bmRequestType & bRequest
* : uint16_t Val ; wValue
* : uint16_t Indx ; wIndex
* : uint16_t Len ; wLength
* Return Value : none
*******************************************************************************/
void usb1_host_SetupStage (uint16_t Req, uint16_t Val, uint16_t Indx, uint16_t Len)
{
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DOING;
USB201.INTSTS1 = (uint16_t)~(USB_HOST_BITSACK | USB_HOST_BITSIGN); /* Status Clear */
USB201.USBREQ = Req;
USB201.USBVAL = Val;
USB201.USBINDX = Indx;
USB201.USBLENG = Len;
USB201.DCPCTR = USB_HOST_BITSUREQ; /* PID=NAK & Send Setup */
}
/*******************************************************************************
* Function Name: usb1_host_StatusStage
* Description : Executes USB control transfer/status stage.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_StatusStage (void)
{
uint8_t Buf1[16];
switch ((g_usb1_host_CmdStage & (USB_HOST_MODE_FIELD)))
{
case USB_HOST_MODE_READ:
usb1_host_CtrlWriteStart((uint32_t)0, (uint8_t*)&Buf1);
break;
case USB_HOST_MODE_WRITE:
usb1_host_CtrlReadStart((uint32_t)0, (uint8_t*)&Buf1);
break;
case USB_HOST_MODE_NO_DATA:
usb1_host_CtrlReadStart((uint32_t)0, (uint8_t*)&Buf1);
break;
default:
break;
}
}
/*******************************************************************************
* Function Name: usb1_host_CtrlWriteStart
* Description : Executes USB control transfer/data stage(write).
* Arguments : uint32_t Bsize ; Data Size
* : uint8_t *Table ; Data Table Address
* Return Value : USB_HOST_WRITESHRT ; End of data write
* : USB_HOST_WRITEEND ; End of data write (not null)
* : USB_HOST_WRITING ; Continue of data write
* : USB_HOST_FIFOERROR ; FIFO access error
*******************************************************************************/
uint16_t usb1_host_CtrlWriteStart (uint32_t Bsize, uint8_t * Table)
{
uint16_t EndFlag_K;
uint16_t mbw;
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DOING;
usb1_host_set_pid_nak(USB_HOST_PIPE0); /* Set NAK */
g_usb1_host_data_count[USB_HOST_PIPE0] = Bsize; /* Transfer size set */
g_usb1_host_data_pointer[USB_HOST_PIPE0] = Table; /* Transfer address set */
USB201.DCPCTR = USB_HOST_BITSQSET; /* SQSET=1, PID=NAK */
#if(1) /* ohci_wrapp */
Userdef_USB_usb1_host_delay_10us(3);
#endif
RZA_IO_RegWrite_16(&USB201.DCPCFG,
1,
USB_DCPCFG_DIR_SHIFT,
USB_DCPCFG_DIR);
mbw = usb1_host_get_mbw(g_usb1_host_data_count[USB_HOST_PIPE0], (uint32_t)g_usb1_host_data_pointer[USB_HOST_PIPE0]);
usb1_host_set_curpipe(USB_HOST_PIPE0, USB_HOST_CUSE, USB_HOST_BITISEL, mbw);
USB201.CFIFOCTR = USB_HOST_BITBCLR; /* Buffer Clear */
usb1_host_clear_pid_stall(USB_HOST_PIPE0);
EndFlag_K = usb1_host_write_buffer_c(USB_HOST_PIPE0);
/* Host Control sequence */
switch (EndFlag_K)
{
case USB_HOST_WRITESHRT: /* End of data write */
g_usb1_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb1_host_CmdStage |= USB_HOST_STAGE_STATUS;
usb1_host_enable_nrdy_int(USB_HOST_PIPE0); /* Error (NORES or STALL) */
usb1_host_enable_bemp_int(USB_HOST_PIPE0); /* Enable Empty Interrupt */
break;
case USB_HOST_WRITEEND: /* End of data write (not null) */
case USB_HOST_WRITING: /* Continue of data write */
usb1_host_enable_nrdy_int(USB_HOST_PIPE0); /* Error (NORES or STALL) */
usb1_host_enable_bemp_int(USB_HOST_PIPE0); /* Enable Empty Interrupt */
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
break;
default:
break;
}
usb1_host_set_pid_buf(USB_HOST_PIPE0); /* Set BUF */
return (EndFlag_K); /* End or Err or Continue */
}
/*******************************************************************************
* Function Name: usb1_host_CtrlReadStart
* Description : Executes USB control transfer/data stage(read).
* Arguments : uint32_t Bsize ; Data Size
* : uint8_t *Table ; Data Table Address
* Return Value : none
*******************************************************************************/
void usb1_host_CtrlReadStart (uint32_t Bsize, uint8_t * Table)
{
uint16_t mbw;
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DOING;
usb1_host_set_pid_nak(USB_HOST_PIPE0); /* Set NAK */
g_usb1_host_data_count[USB_HOST_PIPE0] = Bsize; /* Transfer size set */
g_usb1_host_data_pointer[USB_HOST_PIPE0] = Table; /* Transfer address set */
USB201.DCPCTR = USB_HOST_BITSQSET; /* SQSET=1, PID=NAK */
#if(1) /* ohci_wrapp */
Userdef_USB_usb1_host_delay_10us(3);
#endif
RZA_IO_RegWrite_16(&USB201.DCPCFG,
0,
USB_DCPCFG_DIR_SHIFT,
USB_DCPCFG_DIR);
mbw = usb1_host_get_mbw(g_usb1_host_data_count[USB_HOST_PIPE0], (uint32_t)g_usb1_host_data_pointer[USB_HOST_PIPE0]);
usb1_host_set_curpipe(USB_HOST_PIPE0, USB_HOST_CUSE, USB_HOST_NO, mbw);
USB201.CFIFOCTR = USB_HOST_BITBCLR; /* Buffer Clear */
usb1_host_enable_nrdy_int(USB_HOST_PIPE0); /* Error (NORES or STALL) */
usb1_host_enable_brdy_int(USB_HOST_PIPE0); /* Ok */
usb1_host_clear_pid_stall(USB_HOST_PIPE0);
usb1_host_set_pid_buf(USB_HOST_PIPE0); /* Set BUF */
}
/* End of File */

View file

@ -0,0 +1,889 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_drv_api.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb1_host.h"
#include "dev_drv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb1_host_resetEP(USB_HOST_CFG_PIPETBL_t *tbl);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb1_api_host_init
* Description : Initializes USB module in the USB host mode.
* : USB connection is executed when executing this function in
* : the states that USB device isconnected to the USB port.
* Arguments : uint8_t int_level : USB Module interrupt level
* : USBU16 mode : USB_HOST_HIGH_SPEED
* : USB_HOST_FULL_SPEED
* : uint16_t clockmode : USB Clock mode
* Return Value : USB detach or attach
* : USB_HOST_ATTACH
* : USB_HOST_DETACH
*******************************************************************************/
uint16_t usb1_api_host_init (uint8_t int_level, uint16_t mode, uint16_t clockmode)
{
uint16_t connect;
volatile uint8_t dummy_buf;
CPG.STBCR7 &= 0xfc; /*The clock of USB0/1 modules is permitted */
dummy_buf = CPG.STBCR7; /* (Dummy read) */
g_usb1_host_SupportUsbDeviceSpeed = mode;
usb1_host_setting_interrupt(int_level);
usb1_host_reset_module(clockmode);
g_usb1_host_bchg_flag = USB_HOST_NO;
g_usb1_host_detach_flag = USB_HOST_NO;
g_usb1_host_attach_flag = USB_HOST_NO;
g_usb1_host_driver_state = USB_HOST_DRV_DETACHED;
g_usb1_host_default_max_packet[USB_HOST_DEVICE_0] = 64;
usb1_host_InitModule();
connect = usb1_host_CheckAttach();
if (connect == USB_HOST_ATTACH)
{
g_usb1_host_attach_flag = USB_HOST_YES;
}
else
{
usb1_host_UsbDetach2();
}
return connect;
}
#if(1) /* ohci_wrapp */
#else
/*******************************************************************************
* Function Name: usb1_api_host_enumeration
* Description : Initializes USB module in the USB host mode.
* : USB connection is executed when executing this function in
* : the states that USB device isconnected to the USB port.
* Arguments : uint16_t devadr : device address
* Return Value : DEVDRV_USBH_DETACH_ERR : device detach
* : DEVDRV_SUCCESS : device enumeration success
* : DEVDRV_ERROR : device enumeration error
*******************************************************************************/
int32_t usb1_api_host_enumeration (uint16_t devadr)
{
int32_t ret;
uint16_t driver_sts;
g_usb1_host_setUsbAddress = devadr;
while (1)
{
driver_sts = usb1_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
ret = DEVDRV_USBH_DETACH_ERR;
break;
}
else if (driver_sts == USB_HOST_DRV_CONFIGURED)
{
ret = DEVDRV_SUCCESS;
break;
}
else if (driver_sts == USB_HOST_DRV_STALL)
{
ret = DEVDRV_ERROR;
break;
}
else if (driver_sts == USB_HOST_DRV_NORES)
{
ret = DEVDRV_ERROR;
break;
}
else
{
/* Do Nothing */
}
}
if (driver_sts == USB_HOST_DRV_NORES)
{
while (1)
{
driver_sts = usb1_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
break;
}
}
}
return ret;
}
/*******************************************************************************
* Function Name: usb1_api_host_detach
* Description : USB detach routine
* Arguments : none
* Return Value : USB_HOST_DETACH : USB detach
* : USB_HOST_ATTACH : USB attach
* : DEVDRV_ERROR : error
*******************************************************************************/
int32_t usb1_api_host_detach (void)
{
int32_t ret;
uint16_t driver_sts;
while (1)
{
driver_sts = usb1_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
ret = USB_HOST_DETACH;
break;
}
else if (driver_sts == USB_HOST_DRV_CONFIGURED)
{
ret = USB_HOST_ATTACH;
break;
}
else if (driver_sts == USB_HOST_DRV_STALL)
{
ret = DEVDRV_ERROR;
break;
}
else if (driver_sts == USB_HOST_DRV_NORES)
{
ret = DEVDRV_ERROR;
break;
}
else
{
/* Do Nothing */
}
}
if (driver_sts == USB_HOST_DRV_NORES)
{
while (1)
{
driver_sts = usb1_api_host_GetUsbDeviceState();
if (driver_sts == USB_HOST_DRV_DETACHED)
{
break;
}
}
}
return ret;
}
/*******************************************************************************
* Function Name: usb1_api_host_data_in
* Description : Executes USB transfer as data-in in the argument specified pipe.
* Arguments : uint16_t devadr ; device address
* : uint16_t Pipe ; Pipe Number
* : uint32_t Size ; Data Size
* : uint8_t *data_buf ; Data data_buf Address
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb1_api_host_data_in (uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t * data_buf)
{
int32_t ret;
if (Pipe == USB_HOST_PIPE0)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipemaxp[Pipe], USB_PIPEMAXP_DEVSEL_SHIFT, USB_PIPEMAXP_DEVSEL) != devadr)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[Pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 1)
{
return DEVDRV_ERROR;
}
if (g_usb1_host_pipe_status[Pipe] == USB_HOST_PIPE_IDLE)
{
usb1_host_start_receive_transfer(Pipe, Size, data_buf);
}
else
{
return DEVDRV_ERROR; /* Now pipe is busy */
}
/* waiting for completing routine */
do
{
if (g_usb1_host_detach_flag == USB_HOST_YES)
{
break;
}
if ((g_usb1_host_pipe_status[Pipe] != USB_HOST_PIPE_IDLE) && (g_usb1_host_pipe_status[Pipe] != USB_HOST_PIPE_WAIT))
{
break;
}
} while (1);
if (g_usb1_host_detach_flag == USB_HOST_YES)
{
return DEVDRV_USBH_DETACH_ERR;
}
switch (g_usb1_host_pipe_status[Pipe])
{
case USB_HOST_PIPE_DONE:
ret = DEVDRV_SUCCESS;
break;
case USB_HOST_PIPE_STALL:
ret = DEVDRV_USBH_STALL;
break;
case USB_HOST_PIPE_NORES:
ret = DEVDRV_USBH_COM_ERR;
break;
default:
ret = DEVDRV_ERROR;
break;
}
usb1_host_stop_transfer(Pipe);
g_usb1_host_pipe_status[Pipe] = USB_HOST_PIPE_IDLE;
return ret;
}
/*******************************************************************************
* Function Name: usb1_api_host_data_out
* Description : Executes USB transfer as data-out in the argument specified pipe.
* Arguments : uint16_t devadr ; device address
* : uint16_t Pipe ; Pipe Number
* : uint32_t Size ; Data Size
* : uint8_t *data_buf ; Data data_buf Address
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb1_api_host_data_out (uint16_t devadr, uint16_t Pipe, uint32_t Size, uint8_t * data_buf)
{
int32_t ret;
if (Pipe == USB_HOST_PIPE0)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipemaxp[Pipe], USB_PIPEMAXP_DEVSEL_SHIFT, USB_PIPEMAXP_DEVSEL) != devadr)
{
return DEVDRV_ERROR;
}
if (RZA_IO_RegRead_16(&g_usb1_host_pipecfg[Pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0)
{
return DEVDRV_ERROR;
}
if (g_usb1_host_pipe_status[Pipe] == USB_HOST_PIPE_IDLE)
{
usb1_host_start_send_transfer(Pipe, Size, data_buf);
}
else
{
return DEVDRV_ERROR; /* Now pipe is busy */
}
/* waiting for completing routine */
do
{
if (g_usb1_host_detach_flag == USB_HOST_YES)
{
break;
}
if ((g_usb1_host_pipe_status[Pipe] != USB_HOST_PIPE_IDLE) && (g_usb1_host_pipe_status[Pipe] != USB_HOST_PIPE_WAIT))
{
break;
}
} while (1);
if (g_usb1_host_detach_flag == USB_HOST_YES)
{
return DEVDRV_USBH_DETACH_ERR;
}
switch (g_usb1_host_pipe_status[Pipe])
{
case USB_HOST_PIPE_DONE:
ret = DEVDRV_SUCCESS;
break;
case USB_HOST_PIPE_STALL:
ret = DEVDRV_USBH_STALL;
break;
case USB_HOST_PIPE_NORES:
ret = DEVDRV_USBH_COM_ERR;
break;
default:
ret = DEVDRV_ERROR;
break;
}
usb1_host_stop_transfer(Pipe);
g_usb1_host_pipe_status[Pipe] = USB_HOST_PIPE_IDLE;
return ret;
}
/*******************************************************************************
* Function Name: usb1_api_host_control_transfer
* Description : Executes USB control transfer.
* Arguments : uint16_t devadr ; device address
* : uint16_t Req ; bmRequestType & bRequest
* : uint16_t Val ; wValue
* : uint16_t Indx ; wIndex
* : uint16_t Len ; wLength
* : uint8_t *buf ; Buffer
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_USBH_DETACH_ERR ; device detach
* : DEVDRV_USBH_CTRL_COM_ERR ; device no response
* : DEVDRV_USBH_STALL ; STALL
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb1_api_host_control_transfer (uint16_t devadr, uint16_t Req, uint16_t Val, uint16_t Indx,
uint16_t Len, uint8_t * Buf)
{
int32_t ret;
do
{
ret = usb1_host_CtrlTransStart(devadr, Req, Val, Indx, Len, Buf);
if (ret == DEVDRV_SUCCESS)
{
if (g_usb1_host_detach_flag == USB_HOST_YES)
{
break;
}
if ((g_usb1_host_pipe_status[USB_HOST_PIPE0] != USB_HOST_PIPE_IDLE)
&& (g_usb1_host_pipe_status[USB_HOST_PIPE0] != USB_HOST_PIPE_WAIT))
{
break;
}
}
else
{
return DEVDRV_ERROR;
}
} while (1);
if (g_usb1_host_detach_flag == USB_HOST_YES)
{
return DEVDRV_USBH_DETACH_ERR;
}
switch (g_usb1_host_pipe_status[USB_HOST_PIPE0])
{
case USB_HOST_PIPE_DONE:
ret = DEVDRV_SUCCESS;
break;
case USB_HOST_PIPE_STALL:
ret = DEVDRV_USBH_STALL;
break;
case USB_HOST_PIPE_NORES:
ret = DEVDRV_USBH_CTRL_COM_ERR;
break;
default:
ret = DEVDRV_ERROR;
break;
}
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_IDLE;
return ret;
}
/*******************************************************************************
* Function Name: usb1_api_host_set_endpoint
* Description : Sets end point on the information specified in the argument.
* Arguments : uint16_t devadr ; device address
* : uint8_t *configdescriptor ; device configration descriptor
* : USB_HOST_CFG_PIPETBL_t *user_table ; pipe table
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb1_api_host_set_endpoint (uint16_t devadr, USB_HOST_CFG_PIPETBL_t * user_table, uint8_t * configdescriptor)
{
uint16_t ret;
uint32_t end_point;
uint32_t offset;
uint32_t totalLength;
USB_HOST_CFG_PIPETBL_t * pipe_table;
/* End Point Search */
end_point = 0;
offset = configdescriptor[0];
totalLength = (uint16_t)(configdescriptor[2] + ((uint16_t)configdescriptor[3] << 8));
do
{
if (configdescriptor[offset + 1] == USB_HOST_ENDPOINT_DESC)
{
pipe_table = &user_table[end_point];
if (pipe_table->pipe_number == 0xffff)
{
break;
}
ret = usb1_api_host_SetEndpointTable(devadr, pipe_table, (uint8_t *)&configdescriptor[offset]);
if ((ret != USB_HOST_PIPE_IN) && (ret != USB_HOST_PIPE_OUT))
{
return DEVDRV_ERROR;
}
++end_point;
}
/* Next End Point Search */
offset += configdescriptor[offset];
} while (offset < totalLength);
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb1_api_host_clear_endpoint
* Description : Clears the pipe definition table specified in the argument.
* Arguments : uint16_t pipe_sel : Pipe Number
* : USB_HOST_CFG_PIPETBL_t *user_table : pipe table
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb1_api_host_clear_endpoint (USB_HOST_CFG_PIPETBL_t * user_table)
{
uint16_t pipe;
for (pipe = USB_HOST_PIPE0; pipe <= USB_HOST_MAX_PIPE_NO; ++pipe)
{
if (user_table->pipe_number == 0xffff)
{
break;
}
user_table->pipe_cfg &= (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD);
user_table->pipe_max_pktsize = 0;
user_table->pipe_cycle = 0;
user_table++;
}
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb1_api_host_clear_endpoint_pipe
* Description : Clears the pipe definition table specified in the argument.
* Arguments : USB_HOST_CFG_PIPETBL_t *user_table : pipe table
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb1_api_host_clear_endpoint_pipe (uint16_t pipe_sel, USB_HOST_CFG_PIPETBL_t * user_table)
{
uint16_t pipe;
for (pipe = USB_HOST_PIPE0; pipe <= USB_HOST_MAX_PIPE_NO; ++pipe)
{
if (user_table->pipe_number == 0xffff)
{
break;
}
if (user_table->pipe_number == pipe_sel)
{
user_table->pipe_cfg &= (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD);
user_table->pipe_max_pktsize = 0;
user_table->pipe_cycle = 0;
break;
}
user_table++;
}
return DEVDRV_SUCCESS;
}
#endif
/*******************************************************************************
* Function Name: usb1_api_host_SetEndpointTable
* Description : Sets the end point on the information specified by the argument.
* Arguments : uint16_t devadr : device address
* : USB_HOST_CFG_PIPETBL_t *user_table : pipe table
* : uint8_t *Table : Endpoint descriptor
* Return Value : USB_HOST_DIR_H_IN ; IN endpoint
* : USB_HOST_DIR_H_OUT ; OUT endpoint
* : USB_END_POINT_ERROR ; error
*******************************************************************************/
uint16_t usb1_api_host_SetEndpointTable (uint16_t devadr, USB_HOST_CFG_PIPETBL_t * user_table, uint8_t * Table)
{
uint16_t PipeCfg;
uint16_t PipeMaxp;
uint16_t pipe_number;
uint16_t ret;
uint16_t ret_flag = 0; // avoid warning.
pipe_number = user_table->pipe_number;
if (Table[1] != USB_HOST_ENDPOINT_DESC)
{
return USB_END_POINT_ERROR;
}
switch (Table[3] & USB_HOST_EP_TYPE)
{
case USB_HOST_EP_CNTRL:
ret_flag = USB_END_POINT_ERROR;
break;
case USB_HOST_EP_ISO:
if ((pipe_number != USB_HOST_PIPE1) && (pipe_number != USB_HOST_PIPE2))
{
return USB_END_POINT_ERROR;
}
PipeCfg = USB_HOST_ISO;
break;
case USB_HOST_EP_BULK:
if ((pipe_number < USB_HOST_PIPE1) || (pipe_number > USB_HOST_PIPE5))
{
return USB_END_POINT_ERROR;
}
PipeCfg = USB_HOST_BULK;
break;
case USB_HOST_EP_INT:
if ((pipe_number < USB_HOST_PIPE6) || (pipe_number > USB_HOST_PIPE9))
{
return USB_END_POINT_ERROR;
}
PipeCfg = USB_HOST_INTERRUPT;
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
/* Set pipe configuration table */
if ((Table[2] & USB_HOST_EP_DIR_MASK) == USB_HOST_EP_IN) /* IN(receive) */
{
if (PipeCfg == USB_HOST_ISO)
{
/* Transfer Type is ISO*/
PipeCfg |= USB_HOST_DIR_H_IN;
switch (user_table->fifo_port)
{
case USB_HOST_CUSE:
case USB_HOST_D0USE:
case USB_HOST_D1USE:
case USB_HOST_D0DMA:
case USB_HOST_D1DMA:
PipeCfg |= (uint16_t)(user_table->pipe_cfg & USB_HOST_DBLBFIELD);
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
}
else
{
/* Transfer Type is BULK or INT */
PipeCfg |= (USB_HOST_SHTNAKON | USB_HOST_DIR_H_IN); /* Compulsory SHTNAK */
switch (user_table->fifo_port)
{
case USB_HOST_CUSE:
case USB_HOST_D0USE:
case USB_HOST_D1USE:
PipeCfg |= (uint16_t)(user_table->pipe_cfg & (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD));
break;
case USB_HOST_D0DMA:
case USB_HOST_D1DMA:
PipeCfg |= (uint16_t)(user_table->pipe_cfg & (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD));
#ifdef __USB_DMA_BFRE_ENABLE__
/* this routine cannnot be perfomred if read operation is executed in buffer size */
PipeCfg |= USB_HOST_BFREON;
#endif
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
}
ret = USB_HOST_PIPE_IN;
}
else /* OUT(send) */
{
if (PipeCfg == USB_HOST_ISO)
{
/* Transfer Type is ISO*/
PipeCfg |= (uint16_t)(user_table->pipe_cfg & USB_HOST_DBLBFIELD);
}
else
{
/* Transfer Type is BULK or INT */
PipeCfg |= (uint16_t)(user_table->pipe_cfg & (USB_HOST_DBLBFIELD | USB_HOST_CNTMDFIELD));
}
PipeCfg |= USB_HOST_DIR_H_OUT;
ret = USB_HOST_PIPE_OUT;
}
switch (user_table->fifo_port)
{
case USB_HOST_CUSE:
g_usb1_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_CFIFO_USE;
break;
case USB_HOST_D0USE:
g_usb1_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D0FIFO_USE;
break;
case USB_HOST_D1USE:
g_usb1_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D1FIFO_USE;
break;
case USB_HOST_D0DMA:
g_usb1_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D0FIFO_DMA;
break;
case USB_HOST_D1DMA:
g_usb1_host_PipeTbl[pipe_number] = (uint16_t)USB_HOST_D1FIFO_DMA;
break;
default:
ret_flag = USB_END_POINT_ERROR;
break;
}
if (ret_flag == USB_END_POINT_ERROR)
{
return ret_flag;
}
/* Endpoint number set */
PipeCfg |= (uint16_t)(Table[2] & USB_HOST_EP_NUM_MASK);
g_usb1_host_PipeTbl[pipe_number] |= (uint16_t)(Table[2] & USB_HOST_EP_NUM_MASK);
/* Max packet size set */
PipeMaxp = (uint16_t)((uint16_t)Table[4] | (uint16_t)((uint16_t)Table[5] << 8));
if (PipeMaxp == 0u)
{
return USB_END_POINT_ERROR;
}
/* Set device address */
PipeMaxp |= (uint16_t)(devadr << 12);
user_table->pipe_cfg = PipeCfg;
user_table->pipe_max_pktsize = PipeMaxp;
usb1_host_resetEP(user_table);
return ret;
}
/*******************************************************************************
* Function Name: usb1_host_resetEP
* Description : Sets the end point on the information specified by the argument.
* Arguments : USB_HOST_CFG_PIPETBL_t *tbl : pipe table
* Return Value : none
*******************************************************************************/
static void usb1_host_resetEP (USB_HOST_CFG_PIPETBL_t * tbl)
{
uint16_t pipe;
/* Host pipe */
/* The pipe number of pipe definition table is obtained */
pipe = (uint16_t)(tbl->pipe_number & USB_HOST_BITCURPIPE); /* Pipe Number */
/* FIFO port access pipe is set to initial value */
/* The connection with FIFO should be cut before setting the pipe */
if (RZA_IO_RegRead_16(&USB201.CFIFOSEL,
USB_CFIFOSEL_CURPIPE_SHIFT,
USB_CFIFOSEL_CURPIPE) == pipe)
{
usb1_host_change_fifo_port(USB_HOST_PIPE0, USB_HOST_CUSE, USB_HOST_NO, USB_HOST_BITMBW_16);
}
if (RZA_IO_RegRead_16(&USB201.D0FIFOSEL,
USB_DnFIFOSEL_CURPIPE_SHIFT,
USB_DnFIFOSEL_CURPIPE) == pipe)
{
usb1_host_change_fifo_port(USB_HOST_PIPE0, USB_HOST_D0USE, USB_HOST_NO, USB_HOST_BITMBW_16);
}
if (RZA_IO_RegRead_16(&USB201.D1FIFOSEL,
USB_DnFIFOSEL_CURPIPE_SHIFT,
USB_DnFIFOSEL_CURPIPE) == pipe)
{
usb1_host_change_fifo_port(USB_HOST_PIPE0, USB_HOST_D1USE, USB_HOST_NO, USB_HOST_BITMBW_16);
}
/* Interrupt of pipe set is disabled */
usb1_host_disable_brdy_int(pipe);
usb1_host_disable_nrdy_int(pipe);
usb1_host_disable_bemp_int(pipe);
/* Pipe to set is set to NAK */
usb1_host_set_pid_nak(pipe);
/* Pipe is set */
USB201.PIPESEL = pipe;
USB201.PIPECFG = tbl->pipe_cfg;
USB201.PIPEBUF = tbl->pipe_buf;
USB201.PIPEMAXP = tbl->pipe_max_pktsize;
USB201.PIPEPERI = tbl->pipe_cycle;
g_usb1_host_pipecfg[pipe] = tbl->pipe_cfg;
g_usb1_host_pipebuf[pipe] = tbl->pipe_buf;
g_usb1_host_pipemaxp[pipe] = tbl->pipe_max_pktsize;
g_usb1_host_pipeperi[pipe] = tbl->pipe_cycle;
/* Sequence bit clear */
usb1_host_set_sqclr(pipe);
usb1_host_aclrm(pipe);
usb1_host_set_csclr(pipe);
/* Pipe window selection is set to unused */
USB201.PIPESEL = USB_HOST_PIPE0;
}
#if(1) /* ohci_wrapp */
#else
/*******************************************************************************
* Function Name: usb1_api_host_data_count
* Description : Get g_usb0_host_data_count[pipe]
* Arguments : uint16_t pipe ; Pipe Number
* : uint32_t *data_count ; return g_usb0_data_count[pipe]
* Return Value : DEVDRV_SUCCESS ; success
* : DEVDRV_ERROR ; error
*******************************************************************************/
int32_t usb1_api_host_data_count (uint16_t pipe, uint32_t * data_count)
{
if (pipe > USB_HOST_MAX_PIPE_NO)
{
return DEVDRV_ERROR;
}
*data_count = g_usb1_host_PipeDataSize[pipe];
return DEVDRV_SUCCESS;
}
#endif
/* End of File */

View file

@ -0,0 +1,137 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_global.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb1_host.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
const uint16_t g_usb1_host_bit_set[16] =
{
0x0001, 0x0002, 0x0004, 0x0008,
0x0010, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800,
0x1000, 0x2000, 0x4000, 0x8000
};
uint32_t g_usb1_host_data_count[USB_HOST_MAX_PIPE_NO + 1];
uint8_t * g_usb1_host_data_pointer[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb1_host_PipeIgnore[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb1_host_PipeTbl[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb1_host_pipe_status[USB_HOST_MAX_PIPE_NO + 1];
uint32_t g_usb1_host_PipeDataSize[USB_HOST_MAX_PIPE_NO + 1];
USB_HOST_DMA_t g_usb1_host_DmaInfo[2];
uint16_t g_usb1_host_DmaPipe[2];
uint16_t g_usb1_host_DmaBval[2];
uint16_t g_usb1_host_DmaStatus[2];
uint16_t g_usb1_host_driver_state;
uint16_t g_usb1_host_ConfigNum;
uint16_t g_usb1_host_CmdStage;
uint16_t g_usb1_host_bchg_flag;
uint16_t g_usb1_host_detach_flag;
uint16_t g_usb1_host_attach_flag;
uint16_t g_usb1_host_UsbAddress;
uint16_t g_usb1_host_setUsbAddress;
uint16_t g_usb1_host_default_max_packet[USB_HOST_MAX_DEVICE + 1];
uint16_t g_usb1_host_UsbDeviceSpeed;
uint16_t g_usb1_host_SupportUsbDeviceSpeed;
uint16_t g_usb1_host_SavReq;
uint16_t g_usb1_host_SavVal;
uint16_t g_usb1_host_SavIndx;
uint16_t g_usb1_host_SavLen;
uint16_t g_usb1_host_pipecfg[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb1_host_pipebuf[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb1_host_pipemaxp[USB_HOST_MAX_PIPE_NO + 1];
uint16_t g_usb1_host_pipeperi[USB_HOST_MAX_PIPE_NO + 1];
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb1_host_init_pipe_status
* Description : Initialize pipe status.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_init_pipe_status (void)
{
uint16_t loop;
g_usb1_host_ConfigNum = 0;
for (loop = 0; loop < (USB_HOST_MAX_PIPE_NO + 1); ++loop)
{
g_usb1_host_pipe_status[loop] = USB_HOST_PIPE_IDLE;
g_usb1_host_PipeDataSize[loop] = 0;
/* pipe configuration in usb1_host_resetEP() */
g_usb1_host_pipecfg[loop] = 0;
g_usb1_host_pipebuf[loop] = 0;
g_usb1_host_pipemaxp[loop] = 0;
g_usb1_host_pipeperi[loop] = 0;
}
}
/* End of File */

View file

@ -0,0 +1,497 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_usbint.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb1_host.h"
#if(1) /* ohci_wrapp */
#include "ohci_wrapp_RZ_A1_local.h"
#endif
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb1_host_interrupt1(void);
static void usb1_host_BRDYInterrupt(uint16_t Status, uint16_t Int_enbl);
static void usb1_host_NRDYInterrupt(uint16_t Status, uint16_t Int_enbl);
static void usb1_host_BEMPInterrupt(uint16_t Status, uint16_t Int_enbl);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb1_host_interrupt
* Description : Executes USB interrupt.
* : Register this function in the USB interrupt handler.
* : Set CFIF0 in the pipe set before the interrupt after executing
* : this function.
* Arguments : uint32_t int_sense ; Interrupts detection mode
* : ; INTC_LEVEL_SENSITIVE : Level sense
* : ; INTC_EDGE_TRIGGER : Edge trigger
* Return Value : none
*******************************************************************************/
void usb1_host_interrupt (uint32_t int_sense)
{
uint16_t savepipe1;
uint16_t savepipe2;
uint16_t buffer;
savepipe1 = USB201.CFIFOSEL;
savepipe2 = USB201.PIPESEL;
usb1_host_interrupt1();
/* Control transmission changes ISEL within interruption processing. */
/* For this reason, write return of ISEL cannot be performed. */
buffer = USB201.CFIFOSEL;
buffer &= (uint16_t)~(USB_HOST_BITCURPIPE);
buffer |= (uint16_t)(savepipe1 & USB_HOST_BITCURPIPE);
USB201.CFIFOSEL = buffer;
USB201.PIPESEL = savepipe2;
}
/*******************************************************************************
* Function Name: usb1_host_interrupt1
* Description : Execue the USB interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_interrupt1 (void)
{
uint16_t intsts0;
uint16_t intsts1;
uint16_t intenb0;
uint16_t intenb1;
uint16_t brdysts;
uint16_t nrdysts;
uint16_t bempsts;
uint16_t brdyenb;
uint16_t nrdyenb;
uint16_t bempenb;
volatile uint16_t dumy_sts;
intsts0 = USB201.INTSTS0;
intsts1 = USB201.INTSTS1;
intenb0 = USB201.INTENB0;
intenb1 = USB201.INTENB1;
if ((intsts1 & USB_HOST_BITBCHG) && (intenb1 & USB_HOST_BITBCHGE))
{
USB201.INTSTS1 = (uint16_t)~USB_HOST_BITBCHG;
RZA_IO_RegWrite_16(&USB201.INTENB1,
0,
USB_INTENB1_BCHGE_SHIFT,
USB_INTENB1_BCHGE);
g_usb1_host_bchg_flag = USB_HOST_YES;
}
else if ((intsts1 & USB_HOST_BITSACK) && (intenb1 & USB_HOST_BITSACKE))
{
USB201.INTSTS1 = (uint16_t)~USB_HOST_BITSACK;
#if(1) /* ohci_wrapp */
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
#else
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
#endif
}
else if ((intsts1 & USB_HOST_BITSIGN) && (intenb1 & USB_HOST_BITSIGNE))
{
USB201.INTSTS1 = (uint16_t)~USB_HOST_BITSIGN;
#if(1) /* ohci_wrapp */
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES; /* exit NORES */
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#else
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_NORES;
#endif
}
else if (((intsts1 & USB_HOST_BITDTCH) == USB_HOST_BITDTCH)
&& ((intenb1 & USB_HOST_BITDTCHE) == USB_HOST_BITDTCHE))
{
USB201.INTSTS1 = (uint16_t)~USB_HOST_BITDTCH;
RZA_IO_RegWrite_16(&USB201.INTENB1,
0,
USB_INTENB1_DTCHE_SHIFT,
USB_INTENB1_DTCHE);
g_usb1_host_detach_flag = USB_HOST_YES;
Userdef_USB_usb1_host_detach();
usb1_host_UsbDetach2();
}
else if (((intsts1 & USB_HOST_BITATTCH) == USB_HOST_BITATTCH)
&& ((intenb1 & USB_HOST_BITATTCHE) == USB_HOST_BITATTCHE))
{
USB201.INTSTS1 = (uint16_t)~USB_HOST_BITATTCH;
RZA_IO_RegWrite_16(&USB201.INTENB1,
0,
USB_INTENB1_ATTCHE_SHIFT,
USB_INTENB1_ATTCHE);
g_usb1_host_attach_flag = USB_HOST_YES;
Userdef_USB_usb1_host_attach();
usb1_host_UsbAttach();
}
else if ((intsts0 & intenb0 & (USB_HOST_BITBEMP | USB_HOST_BITNRDY | USB_HOST_BITBRDY)))
{
brdysts = USB201.BRDYSTS;
nrdysts = USB201.NRDYSTS;
bempsts = USB201.BEMPSTS;
brdyenb = USB201.BRDYENB;
nrdyenb = USB201.NRDYENB;
bempenb = USB201.BEMPENB;
if ((intsts0 & USB_HOST_BITBRDY) && (intenb0 & USB_HOST_BITBRDYE) && (brdysts & brdyenb))
{
usb1_host_BRDYInterrupt(brdysts, brdyenb);
}
else if ((intsts0 & USB_HOST_BITBEMP) && (intenb0 & USB_HOST_BITBEMPE) && (bempsts & bempenb))
{
usb1_host_BEMPInterrupt(bempsts, bempenb);
}
else if ((intsts0 & USB_HOST_BITNRDY) && (intenb0 & USB_HOST_BITNRDYE) && (nrdysts & nrdyenb))
{
usb1_host_NRDYInterrupt(nrdysts, nrdyenb);
}
else
{
/* Do Nothing */
}
}
else
{
/* Do Nothing */
}
/* Three dummy read for clearing interrupt requests */
dumy_sts = USB201.INTSTS0;
dumy_sts = USB201.INTSTS1;
}
/*******************************************************************************
* Function Name: usb1_host_BRDYInterrupt
* Description : Executes USB BRDY interrupt.
* Arguments : uint16_t Status ; BRDYSTS Register Value
* : uint16_t Int_enbl ; BRDYENB Register Value
* Return Value : none
*******************************************************************************/
void usb1_host_BRDYInterrupt (uint16_t Status, uint16_t Int_enbl)
{
uint16_t buffer;
volatile uint16_t dumy_sts;
if ((Status & g_usb1_host_bit_set[USB_HOST_PIPE0]) && (Int_enbl & g_usb1_host_bit_set[USB_HOST_PIPE0]))
{
USB201.BRDYSTS = (uint16_t)~g_usb1_host_bit_set[USB_HOST_PIPE0];
#if(1) /* ohci_wrapp */
switch ((g_usb1_host_CmdStage & (USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
buffer = usb1_host_read_buffer_c(USB_HOST_PIPE0);
usb1_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb1_host_read_buffer_c(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_READING: /* Continue of data read */
break;
case USB_HOST_READEND: /* End of data read */
case USB_HOST_READSHRT: /* End of data read */
usb1_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case USB_HOST_READOVER: /* buffer over */
USB201.CFIFOCTR = USB_HOST_BITBCLR;
usb1_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
default:
break;
}
#else
switch ((g_usb1_host_CmdStage & (USB_HOST_MODE_FIELD | USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_MODE_WRITE | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
case (USB_HOST_MODE_NO_DATA | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
buffer = usb1_host_read_buffer_c(USB_HOST_PIPE0);
usb1_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case (USB_HOST_MODE_READ | USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb1_host_read_buffer_c(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_READING: /* Continue of data read */
break;
case USB_HOST_READEND: /* End of data read */
case USB_HOST_READSHRT: /* End of data read */
usb1_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case USB_HOST_READOVER: /* buffer over */
USB201.CFIFOCTR = USB_HOST_BITBCLR;
usb1_host_disable_brdy_int(USB_HOST_PIPE0);
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
default:
break;
}
#endif
}
else
{
usb1_host_brdy_int(Status, Int_enbl);
}
/* Three dummy reads for clearing interrupt requests */
dumy_sts = USB201.BRDYSTS;
}
/*******************************************************************************
* Function Name: usb1_host_NRDYInterrupt
* Description : Executes USB NRDY interrupt.
* Arguments : uint16_t Status ; NRDYSTS Register Value
* : uint16_t Int_enbl ; NRDYENB Register Value
* Return Value : none
*******************************************************************************/
void usb1_host_NRDYInterrupt (uint16_t Status, uint16_t Int_enbl)
{
uint16_t pid;
volatile uint16_t dumy_sts;
if ((Status & g_usb1_host_bit_set[USB_HOST_PIPE0]) && (Int_enbl & g_usb1_host_bit_set[USB_HOST_PIPE0]))
{
USB201.NRDYSTS = (uint16_t)~g_usb1_host_bit_set[USB_HOST_PIPE0];
pid = usb1_host_get_pid(USB_HOST_PIPE0);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_STALL;
#if(1) /* ohci_wrapp */
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#endif
}
else if (pid == USB_HOST_PID_NAK)
{
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_NORES;
#if(1) /* ohci_wrapp */
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_NORES;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#endif
}
else
{
/* Do Nothing */
}
}
else
{
usb1_host_nrdy_int(Status, Int_enbl);
}
/* Three dummy reads for clearing interrupt requests */
dumy_sts = USB201.NRDYSTS;
}
/*******************************************************************************
* Function Name: usb1_host_BEMPInterrupt
* Description : Executes USB BEMP interrupt.
* Arguments : uint16_t Status ; BEMPSTS Register Value
* : uint16_t Int_enbl ; BEMPENB Register Value
* Return Value : none
*******************************************************************************/
void usb1_host_BEMPInterrupt (uint16_t Status, uint16_t Int_enbl)
{
uint16_t buffer;
uint16_t pid;
volatile uint16_t dumy_sts;
if ((Status & g_usb1_host_bit_set[USB_HOST_PIPE0]) && (Int_enbl & g_usb1_host_bit_set[USB_HOST_PIPE0]))
{
USB201.BEMPSTS = (uint16_t)~g_usb1_host_bit_set[USB_HOST_PIPE0];
pid = usb1_host_get_pid(USB_HOST_PIPE0);
if ((pid == USB_HOST_PID_STALL) || (pid == USB_HOST_PID_STALL2))
{
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_STALL;
#if(1) /* ohci_wrapp */
g_usb1_host_pipe_status[USB_HOST_PIPE0] = USB_HOST_PIPE_STALL; /* exit STALL */
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_STALL);
#endif
}
else
{
#if(1) /* ohci_wrapp */
switch ((g_usb1_host_CmdStage & (USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case (USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb1_host_write_buffer(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_WRITING: /* Continue of data write */
case USB_HOST_WRITEEND: /* End of data write (zero-length) */
break;
case USB_HOST_WRITESHRT: /* End of data write */
g_usb1_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb1_host_CmdStage |= USB_HOST_STAGE_STATUS;
ohciwrapp_loc_TransEnd(USB_HOST_PIPE0, TD_CC_NOERROR);
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
default:
/* do nothing */
break;
}
#else
switch ((g_usb1_host_CmdStage & (USB_HOST_MODE_FIELD | USB_HOST_STAGE_FIELD | USB_HOST_CMD_FIELD)))
{
case (USB_HOST_MODE_READ | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_DONE;
break;
case (USB_HOST_MODE_WRITE | USB_HOST_STAGE_DATA | USB_HOST_CMD_DOING):
buffer = usb1_host_write_buffer(USB_HOST_PIPE0);
switch (buffer)
{
case USB_HOST_WRITING: /* Continue of data write */
case USB_HOST_WRITEEND: /* End of data write (zero-length) */
break;
case USB_HOST_WRITESHRT: /* End of data write */
g_usb1_host_CmdStage &= (~USB_HOST_STAGE_FIELD);
g_usb1_host_CmdStage |= USB_HOST_STAGE_STATUS;
break;
case USB_HOST_FIFOERROR: /* FIFO access error */
default:
break;
}
break;
case (USB_HOST_MODE_WRITE | USB_HOST_STAGE_STATUS | USB_HOST_CMD_DOING):
g_usb1_host_CmdStage &= (~USB_HOST_CMD_FIELD);
g_usb1_host_CmdStage |= USB_HOST_CMD_IDLE;
break;
default:
/* do nothing */
break;
}
#endif
}
}
else
{
usb1_host_bemp_int(Status, Int_enbl);
}
/* Three dummy reads for clearing interrupt requests */
dumy_sts = USB201.BEMPSTS;
}
/* End of File */

View file

@ -0,0 +1,637 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_usbsig.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb1_host.h"
#include "dev_drv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb1_host_EnableINT_Module(void);
static void usb1_host_Enable_AttachINT(void);
static void usb1_host_Disable_AttachINT(void);
static void usb1_host_Disable_BchgINT(void);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: usb1_host_InitModule
* Description : Initializes the USB module in USB host module.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_InitModule (void)
{
uint16_t buf1;
uint16_t buf2;
uint16_t buf3;
usb1_host_init_pipe_status();
RZA_IO_RegWrite_16(&USB201.SYSCFG0,
1,
USB_SYSCFG_DCFM_SHIFT,
USB_SYSCFG_DCFM); /* HOST mode */
RZA_IO_RegWrite_16(&USB201.SYSCFG0,
1,
USB_SYSCFG_DRPD_SHIFT,
USB_SYSCFG_DRPD); /* PORT0 D+, D- setting */
do
{
buf1 = RZA_IO_RegRead_16(&USB201.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb1_host_delay_xms(50);
buf2 = RZA_IO_RegRead_16(&USB201.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb1_host_delay_xms(50);
buf3 = RZA_IO_RegRead_16(&USB201.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
} while ((buf1 != buf2) || (buf1 != buf3));
RZA_IO_RegWrite_16(&USB201.SYSCFG0,
1,
USB_SYSCFG_USBE_SHIFT,
USB_SYSCFG_USBE);
USB201.CFIFOSEL = (uint16_t)(USB_HOST_BITRCNT | USB_HOST_BITMBW_8 | USB_HOST_BITBYTE_LITTLE);
USB201.D0FIFOSEL = (uint16_t)( USB_HOST_BITMBW_8 | USB_HOST_BITBYTE_LITTLE);
USB201.D1FIFOSEL = (uint16_t)( USB_HOST_BITMBW_8 | USB_HOST_BITBYTE_LITTLE);
}
/*******************************************************************************
* Function Name: usb1_host_CheckAttach
* Description : Returns the USB device connection state.
* Arguments : none
* Return Value : uint16_t ; USB_HOST_ATTACH : Attached
* : ; USB_HOST_DETACH : not Attached
*******************************************************************************/
uint16_t usb1_host_CheckAttach (void)
{
uint16_t buf1;
uint16_t buf2;
uint16_t buf3;
uint16_t rhst;
do
{
buf1 = RZA_IO_RegRead_16(&USB201.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb1_host_delay_xms(50);
buf2 = RZA_IO_RegRead_16(&USB201.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
Userdef_USB_usb1_host_delay_xms(50);
buf3 = RZA_IO_RegRead_16(&USB201.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
} while ((buf1 != buf2) || (buf1 != buf3));
rhst = RZA_IO_RegRead_16(&USB201.DVSTCTR0,
USB_DVSTCTR0_RHST_SHIFT,
USB_DVSTCTR0_RHST);
if (rhst == USB_HOST_UNDECID)
{
if (buf1 == USB_HOST_FS_JSTS)
{
if (g_usb1_host_SupportUsbDeviceSpeed == USB_HOST_HIGH_SPEED)
{
RZA_IO_RegWrite_16(&USB201.SYSCFG0,
1,
USB_SYSCFG_HSE_SHIFT,
USB_SYSCFG_HSE);
}
else
{
RZA_IO_RegWrite_16(&USB201.SYSCFG0,
0,
USB_SYSCFG_HSE_SHIFT,
USB_SYSCFG_HSE);
}
return USB_HOST_ATTACH;
}
else if (buf1 == USB_HOST_LS_JSTS)
{
/* Low Speed Device */
RZA_IO_RegWrite_16(&USB201.SYSCFG0,
0,
USB_SYSCFG_HSE_SHIFT,
USB_SYSCFG_HSE);
return USB_HOST_ATTACH;
}
else
{
/* Do Nothing */
}
}
else if ((rhst == USB_HOST_HSMODE) || (rhst == USB_HOST_FSMODE))
{
return USB_HOST_ATTACH;
}
else if (rhst == USB_HOST_LSMODE)
{
return USB_HOST_ATTACH;
}
else
{
/* Do Nothing */
}
return USB_HOST_DETACH;
}
/*******************************************************************************
* Function Name: usb1_host_UsbAttach
* Description : Connects the USB device.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_UsbAttach (void)
{
usb1_host_EnableINT_Module();
usb1_host_Disable_BchgINT();
usb1_host_Disable_AttachINT();
usb1_host_Enable_DetachINT();
}
/*******************************************************************************
* Function Name: usb1_host_UsbDetach
* Description : Disconnects the USB device.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_UsbDetach (void)
{
uint16_t pipe;
uint16_t devadr;
g_usb1_host_driver_state = USB_HOST_DRV_DETACHED;
/* Terminate all the pipes in which communications on port */
/* are currently carried out */
for (pipe = 0; pipe < (USB_HOST_MAX_PIPE_NO + 1); ++pipe)
{
if (g_usb1_host_pipe_status[pipe] != USB_HOST_PIPE_IDLE)
{
if (pipe == USB_HOST_PIPE0)
{
devadr = RZA_IO_RegRead_16(&USB201.DCPMAXP,
USB_DCPMAXP_DEVSEL_SHIFT,
USB_DCPMAXP_DEVSEL);
}
else
{
devadr = RZA_IO_RegRead_16(&g_usb1_host_pipemaxp[pipe], USB_PIPEMAXP_DEVSEL_SHIFT, USB_PIPEMAXP_DEVSEL);
}
if (devadr == g_usb1_host_UsbAddress)
{
usb1_host_stop_transfer(pipe);
}
g_usb1_host_pipe_status[pipe] = USB_HOST_PIPE_IDLE;
}
}
g_usb1_host_ConfigNum = 0;
g_usb1_host_UsbAddress = 0;
g_usb1_host_default_max_packet[USB_HOST_DEVICE_0] = 64;
usb1_host_UsbDetach2();
}
/*******************************************************************************
* Function Name: usb1_host_UsbDetach2
* Description : Disconnects the USB device.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_UsbDetach2 (void)
{
usb1_host_Disable_DetachINT();
usb1_host_Disable_BchgINT();
usb1_host_Enable_AttachINT();
}
/*******************************************************************************
* Function Name: usb1_host_UsbBusReset
* Description : Issues the USB bus reset signal.
* Arguments : none
* Return Value : uint16_t ; RHST
*******************************************************************************/
uint16_t usb1_host_UsbBusReset (void)
{
uint16_t buffer;
uint16_t loop;
RZA_IO_RegWrite_16(&USB201.DVSTCTR0,
1,
USB_DVSTCTR0_USBRST_SHIFT,
USB_DVSTCTR0_USBRST);
RZA_IO_RegWrite_16(&USB201.DVSTCTR0,
0,
USB_DVSTCTR0_UACT_SHIFT,
USB_DVSTCTR0_UACT);
Userdef_USB_usb1_host_delay_xms(50);
buffer = USB201.DVSTCTR0;
buffer &= (uint16_t)(~(USB_HOST_BITRST));
buffer |= USB_HOST_BITUACT;
USB201.DVSTCTR0 = buffer;
Userdef_USB_usb1_host_delay_xms(20);
for (loop = 0, buffer = USB_HOST_HSPROC; loop < 3; ++loop)
{
buffer = RZA_IO_RegRead_16(&USB201.DVSTCTR0,
USB_DVSTCTR0_RHST_SHIFT,
USB_DVSTCTR0_RHST);
if (buffer == USB_HOST_HSPROC)
{
Userdef_USB_usb1_host_delay_xms(10);
}
else
{
break;
}
}
return buffer;
}
/*******************************************************************************
* Function Name: usb1_host_UsbResume
* Description : Issues the USB resume signal.
* Arguments : none
* Return Value : int32_t ; DEVDRV_SUCCESS
* : ; DEVDRV_ERROR
*******************************************************************************/
int32_t usb1_host_UsbResume (void)
{
uint16_t buf;
if ((g_usb1_host_driver_state & USB_HOST_DRV_SUSPEND) == 0)
{
/* not SUSPEND */
return DEVDRV_ERROR;
}
RZA_IO_RegWrite_16(&USB201.INTENB1,
0,
USB_INTENB1_BCHGE_SHIFT,
USB_INTENB1_BCHGE);
RZA_IO_RegWrite_16(&USB201.DVSTCTR0,
1,
USB_DVSTCTR0_RESUME_SHIFT,
USB_DVSTCTR0_RESUME);
Userdef_USB_usb1_host_delay_xms(20);
buf = USB201.DVSTCTR0;
buf &= (uint16_t)(~(USB_HOST_BITRESUME));
buf |= USB_HOST_BITUACT;
USB201.DVSTCTR0 = buf;
g_usb1_host_driver_state &= (uint16_t)~USB_HOST_DRV_SUSPEND;
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb1_host_UsbSuspend
* Description : Issues the USB suspend signal.
* Arguments : none
* Return Value : int32_t ; DEVDRV_SUCCESS :not SUSPEND
* : ; DEVDRV_ERROR :SUSPEND
*******************************************************************************/
int32_t usb1_host_UsbSuspend (void)
{
uint16_t buf;
if ((g_usb1_host_driver_state & USB_HOST_DRV_SUSPEND) != 0)
{
/* SUSPEND */
return DEVDRV_ERROR;
}
RZA_IO_RegWrite_16(&USB201.DVSTCTR0,
0,
USB_DVSTCTR0_UACT_SHIFT,
USB_DVSTCTR0_UACT);
Userdef_USB_usb1_host_delay_xms(5);
buf = RZA_IO_RegRead_16(&USB201.SYSSTS0,
USB_SYSSTS0_LNST_SHIFT,
USB_SYSSTS0_LNST);
if ((buf != USB_HOST_FS_JSTS) && (buf != USB_HOST_LS_JSTS))
{
usb1_host_UsbDetach();
}
else
{
g_usb1_host_driver_state |= USB_HOST_DRV_SUSPEND;
}
return DEVDRV_SUCCESS;
}
/*******************************************************************************
* Function Name: usb1_host_Enable_DetachINT
* Description : Enables the USB disconnection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_Enable_DetachINT (void)
{
USB201.INTSTS1 = (uint16_t)(~(USB_HOST_BITDTCH));
RZA_IO_RegWrite_16(&USB201.INTENB1,
1,
USB_INTENB1_DTCHE_SHIFT,
USB_INTENB1_DTCHE);
}
/*******************************************************************************
* Function Name: usb1_host_Disable_DetachINT
* Description : Disables the USB disconnection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_Disable_DetachINT (void)
{
USB201.INTSTS1 = (uint16_t)(~(USB_HOST_BITDTCH));
RZA_IO_RegWrite_16(&USB201.INTENB1,
0,
USB_INTENB1_DTCHE_SHIFT,
USB_INTENB1_DTCHE);
}
/*******************************************************************************
* Function Name: usb1_host_Enable_AttachINT
* Description : Enables the USB connection detection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_Enable_AttachINT (void)
{
USB201.INTSTS1 = (uint16_t)(~(USB_HOST_BITATTCH));
RZA_IO_RegWrite_16(&USB201.INTENB1,
1,
USB_INTENB1_ATTCHE_SHIFT,
USB_INTENB1_ATTCHE);
}
/*******************************************************************************
* Function Name: usb1_host_Disable_AttachINT
* Description : Disables the USB connection detection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_Disable_AttachINT (void)
{
USB201.INTSTS1 = (uint16_t)(~(USB_HOST_BITATTCH));
RZA_IO_RegWrite_16(&USB201.INTENB1,
0,
USB_INTENB1_ATTCHE_SHIFT,
USB_INTENB1_ATTCHE);
}
/*******************************************************************************
* Function Name: usb1_host_Disable_BchgINT
* Description : Disables the USB bus change detection interrupt.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_Disable_BchgINT (void)
{
USB201.INTSTS1 = (uint16_t)(~(USB_HOST_BITBCHG));
RZA_IO_RegWrite_16(&USB201.INTENB1,
0,
USB_INTENB1_BCHGE_SHIFT,
USB_INTENB1_BCHGE);
}
/*******************************************************************************
* Function Name: usb1_host_set_devadd
* Description : DEVADDn register is set by specified value
* Arguments : uint16_t addr : Device address
* : uint16_t *devadd : Set value
* Return Value : none
*******************************************************************************/
void usb1_host_set_devadd (uint16_t addr, uint16_t * devadd)
{
uint16_t * ptr;
uint16_t ret_flag = DEVDRV_FLAG_ON; // avoid warning.
switch (addr)
{
case USB_HOST_DEVICE_0:
ptr = (uint16_t *)&USB201.DEVADD0;
break;
case USB_HOST_DEVICE_1:
ptr = (uint16_t *)&USB201.DEVADD1;
break;
case USB_HOST_DEVICE_2:
ptr = (uint16_t *)&USB201.DEVADD2;
break;
case USB_HOST_DEVICE_3:
ptr = (uint16_t *)&USB201.DEVADD3;
break;
case USB_HOST_DEVICE_4:
ptr = (uint16_t *)&USB201.DEVADD4;
break;
case USB_HOST_DEVICE_5:
ptr = (uint16_t *)&USB201.DEVADD5;
break;
case USB_HOST_DEVICE_6:
ptr = (uint16_t *)&USB201.DEVADD6;
break;
case USB_HOST_DEVICE_7:
ptr = (uint16_t *)&USB201.DEVADD7;
break;
case USB_HOST_DEVICE_8:
ptr = (uint16_t *)&USB201.DEVADD8;
break;
case USB_HOST_DEVICE_9:
ptr = (uint16_t *)&USB201.DEVADD9;
break;
case USB_HOST_DEVICE_10:
ptr = (uint16_t *)&USB201.DEVADDA;
break;
default:
ret_flag = DEVDRV_FLAG_OFF;
break;
}
if (ret_flag == DEVDRV_FLAG_ON)
{
*ptr = (uint16_t)(*devadd & USB_HOST_DEVADD_MASK);
}
}
/*******************************************************************************
* Function Name: usb1_host_get_devadd
* Description : DEVADDn register is obtained
* Arguments : uint16_t addr : Device address
* : uint16_t *devadd : USB_HOST_DEVADD register value
* Return Value : none
*******************************************************************************/
void usb1_host_get_devadd (uint16_t addr, uint16_t * devadd)
{
uint16_t * ptr;
uint16_t ret_flag = DEVDRV_FLAG_ON; // avoid warning.
switch (addr)
{
case USB_HOST_DEVICE_0:
ptr = (uint16_t *)&USB201.DEVADD0;
break;
case USB_HOST_DEVICE_1:
ptr = (uint16_t *)&USB201.DEVADD1;
break;
case USB_HOST_DEVICE_2:
ptr = (uint16_t *)&USB201.DEVADD2;
break;
case USB_HOST_DEVICE_3:
ptr = (uint16_t *)&USB201.DEVADD3;
break;
case USB_HOST_DEVICE_4:
ptr = (uint16_t *)&USB201.DEVADD4;
break;
case USB_HOST_DEVICE_5:
ptr = (uint16_t *)&USB201.DEVADD5;
break;
case USB_HOST_DEVICE_6:
ptr = (uint16_t *)&USB201.DEVADD6;
break;
case USB_HOST_DEVICE_7:
ptr = (uint16_t *)&USB201.DEVADD7;
break;
case USB_HOST_DEVICE_8:
ptr = (uint16_t *)&USB201.DEVADD8;
break;
case USB_HOST_DEVICE_9:
ptr = (uint16_t *)&USB201.DEVADD9;
break;
case USB_HOST_DEVICE_10:
ptr = (uint16_t *)&USB201.DEVADDA;
break;
default:
ret_flag = DEVDRV_FLAG_OFF;
break;
}
if (ret_flag == DEVDRV_FLAG_ON)
{
*devadd = *ptr;
}
}
/*******************************************************************************
* Function Name: usb1_host_EnableINT_Module
* Description : Enables BEMP/NRDY/BRDY interrupt and SIGN/SACK interrupt.
* : Enables NRDY/BEMP interrupt in the pipe0.
* Arguments : none
* Return Value : none
*******************************************************************************/
void usb1_host_EnableINT_Module (void)
{
uint16_t buf;
buf = USB201.INTENB0;
buf |= (USB_HOST_BITBEMPE | USB_HOST_BITNRDYE | USB_HOST_BITBRDYE);
USB201.INTENB0 = buf;
buf = USB201.INTENB1;
buf |= (USB_HOST_BITSIGNE | USB_HOST_BITSACKE);
USB201.INTENB1 = buf;
usb1_host_enable_nrdy_int(USB_HOST_PIPE0);
usb1_host_enable_bemp_int(USB_HOST_PIPE0);
}
/* End of File */

View file

@ -0,0 +1,698 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_dmacdrv.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include "r_typedefs.h"
#include "iodefine.h"
#include "rza_io_regrw.h"
#include "usb1_host_dmacdrv.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
#define DMAC_INDEFINE (255) /* Macro definition when REQD bit is not used */
/* ==== Request setting information for on-chip peripheral module ==== */
typedef enum dmac_peri_req_reg_type
{
DMAC_REQ_MID,
DMAC_REQ_RID,
DMAC_REQ_AM,
DMAC_REQ_LVL,
DMAC_REQ_REQD
} dmac_peri_req_reg_type_t;
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/* ==== Prototype declaration ==== */
/* ==== Global variable ==== */
/* On-chip peripheral module request setting table */
static const uint8_t usb1_host_dmac_peri_req_init_table[8][5] =
{
/* MID,RID, AM,LVL,REQD */
{ 32, 3, 2, 1, 1}, /* USB_0 channel 0 transmit FIFO empty */
{ 32, 3, 2, 1, 0}, /* USB_0 channel 0 receive FIFO full */
{ 33, 3, 2, 1, 1}, /* USB_0 channel 1 transmit FIFO empty */
{ 33, 3, 2, 1, 0}, /* USB_0 channel 1 receive FIFO full */
{ 34, 3, 2, 1, 1}, /* USB_1 channel 0 transmit FIFO empty */
{ 34, 3, 2, 1, 0}, /* USB_1 channel 0 receive FIFO full */
{ 35, 3, 2, 1, 1}, /* USB_1 channel 1 transmit FIFO empty */
{ 35, 3, 2, 1, 0}, /* USB_1 channel 1 receive FIFO full */
};
/*******************************************************************************
* Function Name: usb1_host_DMAC3_PeriReqInit
* Description : Sets the register mode for DMA mode and the on-chip peripheral
* : module request for transfer request for DMAC channel 3.
* : Executes DMAC initial setting using the DMA information
* : specified by the argument *trans_info and the enabled/disabled
* : continuous transfer specified by the argument continuation.
* : Registers DMAC channel 3 interrupt handler function and sets
* : the interrupt priority level. Then enables transfer completion
* : interrupt.
* Arguments : dmac_transinfo_t * trans_info : Setting information to DMAC
* : : register
* : uint32_t dmamode : DMA mode (only for DMAC_MODE_REGISTER)
* : uint32_t continuation : Set continuous transfer to be valid
* : : after DMA transfer has been completed
* : DMAC_SAMPLE_CONTINUATION : Execute continuous transfer
* : DMAC_SAMPLE_SINGLE : Do not execute continuous
* : : transfer
* : uint32_t request_factor : Factor for on-chip peripheral module
* : : request
* : DMAC_REQ_OSTM0TINT : OSTM_0 compare match
* : DMAC_REQ_OSTM1TINT : OSTM_1 compare match
* : DMAC_REQ_TGI0A : MTU2_0 input capture/compare match
* : :
* : uint32_t req_direction : Setting value of CHCFG_n register
* : : REQD bit
* Return Value : none
*******************************************************************************/
void usb1_host_DMAC3_PeriReqInit (const dmac_transinfo_t * trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction)
{
/* ==== Register mode ==== */
if (DMAC_MODE_REGISTER == dmamode)
{
/* ==== Next0 register set ==== */
DMAC3.N0SA_n = trans_info->src_addr; /* Start address of transfer source */
DMAC3.N0DA_n = trans_info->dst_addr; /* Start address of transfer destination */
DMAC3.N0TB_n = trans_info->count; /* Total transfer byte count */
/* DAD : Transfer destination address counting direction */
/* SAD : Transfer source address counting direction */
/* DDS : Transfer destination transfer size */
/* SDS : Transfer source transfer size */
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
trans_info->daddr_dir,
DMAC3_CHCFG_n_DAD_SHIFT,
DMAC3_CHCFG_n_DAD);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
trans_info->saddr_dir,
DMAC3_CHCFG_n_SAD_SHIFT,
DMAC3_CHCFG_n_SAD);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
trans_info->dst_size,
DMAC3_CHCFG_n_DDS_SHIFT,
DMAC3_CHCFG_n_DDS);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
trans_info->src_size,
DMAC3_CHCFG_n_SDS_SHIFT,
DMAC3_CHCFG_n_SDS);
/* DMS : Register mode */
/* RSEL : Select Next0 register set */
/* SBE : No discharge of buffer data when aborted */
/* DEM : No DMA interrupt mask */
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_DMS_SHIFT,
DMAC3_CHCFG_n_DMS);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_RSEL_SHIFT,
DMAC3_CHCFG_n_RSEL);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_SBE_SHIFT,
DMAC3_CHCFG_n_SBE);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_DEM_SHIFT,
DMAC3_CHCFG_n_DEM);
/* ---- Continuous transfer ---- */
if (DMAC_SAMPLE_CONTINUATION == continuation)
{
/* REN : Execute continuous transfer */
/* RSW : Change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
1,
DMAC3_CHCFG_n_REN_SHIFT,
DMAC3_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
1,
DMAC3_CHCFG_n_RSW_SHIFT,
DMAC3_CHCFG_n_RSW);
}
/* ---- Single transfer ---- */
else
{
/* REN : Do not execute continuous transfer */
/* RSW : Do not change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_REN_SHIFT,
DMAC3_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_RSW_SHIFT,
DMAC3_CHCFG_n_RSW);
}
/* TM : Single transfer */
/* SEL : Channel setting */
/* HIEN, LOEN : On-chip peripheral module request */
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_TM_SHIFT,
DMAC3_CHCFG_n_TM);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
3,
DMAC3_CHCFG_n_SEL_SHIFT,
DMAC3_CHCFG_n_SEL);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
1,
DMAC3_CHCFG_n_HIEN_SHIFT,
DMAC3_CHCFG_n_HIEN);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
0,
DMAC3_CHCFG_n_LOEN_SHIFT,
DMAC3_CHCFG_n_LOEN);
/* ---- Set factor by specified on-chip peripheral module request ---- */
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_AM],
DMAC3_CHCFG_n_AM_SHIFT,
DMAC3_CHCFG_n_AM);
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_LVL],
DMAC3_CHCFG_n_LVL_SHIFT,
DMAC3_CHCFG_n_LVL);
if (usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD] != DMAC_INDEFINE)
{
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD],
DMAC3_CHCFG_n_REQD_SHIFT,
DMAC3_CHCFG_n_REQD);
}
else
{
RZA_IO_RegWrite_32(&DMAC3.CHCFG_n,
req_direction,
DMAC3_CHCFG_n_REQD_SHIFT,
DMAC3_CHCFG_n_REQD);
}
RZA_IO_RegWrite_32(&DMAC23.DMARS,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_RID],
DMAC23_DMARS_CH3_RID_SHIFT,
DMAC23_DMARS_CH3_RID);
RZA_IO_RegWrite_32(&DMAC23.DMARS,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_MID],
DMAC23_DMARS_CH3_MID_SHIFT,
DMAC23_DMARS_CH3_MID);
/* PR : Round robin mode */
RZA_IO_RegWrite_32(&DMAC07.DCTRL_0_7,
1,
DMAC07_DCTRL_0_7_PR_SHIFT,
DMAC07_DCTRL_0_7_PR);
}
}
/*******************************************************************************
* Function Name: usb1_host_DMAC3_Open
* Description : Enables DMAC channel 3 transfer.
* Arguments : uint32_t req : DMAC request mode
* Return Value : 0 : Succeeded in enabling DMA transfer
* : -1 : Failed to enable DMA transfer (due to DMA operation)
*******************************************************************************/
int32_t usb1_host_DMAC3_Open (uint32_t req)
{
int32_t ret;
volatile uint8_t dummy;
/* Transferable? */
if ((0 == RZA_IO_RegRead_32(&DMAC3.CHSTAT_n,
DMAC3_CHSTAT_n_EN_SHIFT,
DMAC3_CHSTAT_n_EN)) &&
(0 == RZA_IO_RegRead_32(&DMAC3.CHSTAT_n,
DMAC3_CHSTAT_n_TACT_SHIFT,
DMAC3_CHSTAT_n_TACT)))
{
/* Clear Channel Status Register */
RZA_IO_RegWrite_32(&DMAC3.CHCTRL_n,
1,
DMAC3_CHCTRL_n_SWRST_SHIFT,
DMAC3_CHCTRL_n_SWRST);
dummy = RZA_IO_RegRead_32(&DMAC3.CHCTRL_n,
DMAC3_CHCTRL_n_SWRST_SHIFT,
DMAC3_CHCTRL_n_SWRST);
/* Enable DMA transfer */
RZA_IO_RegWrite_32(&DMAC3.CHCTRL_n,
1,
DMAC3_CHCTRL_n_SETEN_SHIFT,
DMAC3_CHCTRL_n_SETEN);
/* ---- Request by software ---- */
if (DMAC_REQ_MODE_SOFT == req)
{
/* DMA transfer Request by software */
RZA_IO_RegWrite_32(&DMAC3.CHCTRL_n,
1,
DMAC3_CHCTRL_n_STG_SHIFT,
DMAC3_CHCTRL_n_STG);
}
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************
* Function Name: usb1_host_DMAC3_Close
* Description : Aborts DMAC channel 3 transfer. Returns the remaining transfer
* : byte count at the time of DMA transfer abort to the argument
* : *remain.
* Arguments : uint32_t * remain : Remaining transfer byte count when
* : : DMA transfer is aborted
* Return Value : none
*******************************************************************************/
void usb1_host_DMAC3_Close (uint32_t * remain)
{
/* ==== Abort transfer ==== */
RZA_IO_RegWrite_32(&DMAC3.CHCTRL_n,
1,
DMAC3_CHCTRL_n_CLREN_SHIFT,
DMAC3_CHCTRL_n_CLREN);
while (1 == RZA_IO_RegRead_32(&DMAC3.CHSTAT_n,
DMAC3_CHSTAT_n_TACT_SHIFT,
DMAC3_CHSTAT_n_TACT))
{
/* Loop until transfer is aborted */
}
while (1 == RZA_IO_RegRead_32(&DMAC3.CHSTAT_n,
DMAC3_CHSTAT_n_EN_SHIFT,
DMAC3_CHSTAT_n_EN))
{
/* Loop until 0 is set in EN before checking the remaining transfer byte count */
}
/* ==== Obtain remaining transfer byte count ==== */
*remain = DMAC3.CRTB_n;
}
/*******************************************************************************
* Function Name: usb1_host_DMAC3_Load_Set
* Description : Sets the transfer source address, transfer destination
* : address, and total transfer byte count respectively
* : specified by the argument src_addr, dst_addr, and count to
* : DMAC channel 3 as DMA transfer information.
* : Sets the register set selected by the CHCFG_n register
* : RSEL bit from the Next0 or Next1 register set.
* : This function should be called when DMA transfer of DMAC
* : channel 3 is aboted.
* Arguments : uint32_t src_addr : Transfer source address
* : uint32_t dst_addr : Transfer destination address
* : uint32_t count : Total transfer byte count
* Return Value : none
*******************************************************************************/
void usb1_host_DMAC3_Load_Set (uint32_t src_addr, uint32_t dst_addr, uint32_t count)
{
uint8_t reg_set;
/* Obtain register set in use */
reg_set = RZA_IO_RegRead_32(&DMAC3.CHSTAT_n,
DMAC3_CHSTAT_n_SR_SHIFT,
DMAC3_CHSTAT_n_SR);
/* ==== Load ==== */
if (0 == reg_set)
{
/* ---- Next0 Register Set ---- */
DMAC3.N0SA_n = src_addr; /* Start address of transfer source */
DMAC3.N0DA_n = dst_addr; /* Start address of transfer destination */
DMAC3.N0TB_n = count; /* Total transfer byte count */
}
else
{
/* ---- Next1 Register Set ---- */
DMAC3.N1SA_n = src_addr; /* Start address of transfer source */
DMAC3.N1DA_n = dst_addr; /* Start address of transfer destination */
DMAC3.N1TB_n = count; /* Total transfer byte count */
}
}
/*******************************************************************************
* Function Name: usb1_host_DMAC4_PeriReqInit
* Description : Sets the register mode for DMA mode and the on-chip peripheral
* : module request for transfer request for DMAC channel 4.
* : Executes DMAC initial setting using the DMA information
* : specified by the argument *trans_info and the enabled/disabled
* : continuous transfer specified by the argument continuation.
* : Registers DMAC channel 4 interrupt handler function and sets
* : the interrupt priority level. Then enables transfer completion
* : interrupt.
* Arguments : dmac_transinfo_t * trans_info : Setting information to DMAC
* : : register
* : uint32_t dmamode : DMA mode (only for DMAC_MODE_REGISTER)
* : uint32_t continuation : Set continuous transfer to be valid
* : : after DMA transfer has been completed
* : DMAC_SAMPLE_CONTINUATION : Execute continuous transfer
* : DMAC_SAMPLE_SINGLE : Do not execute continuous
* : : transfer
* : uint32_t request_factor : Factor for on-chip peripheral module
* : : request
* : DMAC_REQ_OSTM0TINT : OSTM_0 compare match
* : DMAC_REQ_OSTM1TINT : OSTM_1 compare match
* : DMAC_REQ_TGI0A : MTU2_0 input capture/compare match
* : :
* : uint32_t req_direction : Setting value of CHCFG_n register
* : : REQD bit
* Return Value : none
*******************************************************************************/
void usb1_host_DMAC4_PeriReqInit (const dmac_transinfo_t * trans_info, uint32_t dmamode, uint32_t continuation,
uint32_t request_factor, uint32_t req_direction)
{
/* ==== Register mode ==== */
if (DMAC_MODE_REGISTER == dmamode)
{
/* ==== Next0 register set ==== */
DMAC4.N0SA_n = trans_info->src_addr; /* Start address of transfer source */
DMAC4.N0DA_n = trans_info->dst_addr; /* Start address of transfer destination */
DMAC4.N0TB_n = trans_info->count; /* Total transfer byte count */
/* DAD : Transfer destination address counting direction */
/* SAD : Transfer source address counting direction */
/* DDS : Transfer destination transfer size */
/* SDS : Transfer source transfer size */
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
trans_info->daddr_dir,
DMAC4_CHCFG_n_DAD_SHIFT,
DMAC4_CHCFG_n_DAD);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
trans_info->saddr_dir,
DMAC4_CHCFG_n_SAD_SHIFT,
DMAC4_CHCFG_n_SAD);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
trans_info->dst_size,
DMAC4_CHCFG_n_DDS_SHIFT,
DMAC4_CHCFG_n_DDS);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
trans_info->src_size,
DMAC4_CHCFG_n_SDS_SHIFT,
DMAC4_CHCFG_n_SDS);
/* DMS : Register mode */
/* RSEL : Select Next0 register set */
/* SBE : No discharge of buffer data when aborted */
/* DEM : No DMA interrupt mask */
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_DMS_SHIFT,
DMAC4_CHCFG_n_DMS);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_RSEL_SHIFT,
DMAC4_CHCFG_n_RSEL);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_SBE_SHIFT,
DMAC4_CHCFG_n_SBE);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_DEM_SHIFT,
DMAC4_CHCFG_n_DEM);
/* ---- Continuous transfer ---- */
if (DMAC_SAMPLE_CONTINUATION == continuation)
{
/* REN : Execute continuous transfer */
/* RSW : Change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
1,
DMAC4_CHCFG_n_REN_SHIFT,
DMAC4_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
1,
DMAC4_CHCFG_n_RSW_SHIFT,
DMAC4_CHCFG_n_RSW);
}
/* ---- Single transfer ---- */
else
{
/* REN : Do not execute continuous transfer */
/* RSW : Do not change register set when DMA transfer is completed. */
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_REN_SHIFT,
DMAC4_CHCFG_n_REN);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_RSW_SHIFT,
DMAC4_CHCFG_n_RSW);
}
/* TM : Single transfer */
/* SEL : Channel setting */
/* HIEN, LOEN : On-chip peripheral module request */
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_TM_SHIFT,
DMAC4_CHCFG_n_TM);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
4,
DMAC4_CHCFG_n_SEL_SHIFT,
DMAC4_CHCFG_n_SEL);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
1,
DMAC4_CHCFG_n_HIEN_SHIFT,
DMAC4_CHCFG_n_HIEN);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
0,
DMAC4_CHCFG_n_LOEN_SHIFT,
DMAC4_CHCFG_n_LOEN);
/* ---- Set factor by specified on-chip peripheral module request ---- */
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_AM],
DMAC4_CHCFG_n_AM_SHIFT,
DMAC4_CHCFG_n_AM);
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_LVL],
DMAC4_CHCFG_n_LVL_SHIFT,
DMAC4_CHCFG_n_LVL);
if (usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD] != DMAC_INDEFINE)
{
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_REQD],
DMAC4_CHCFG_n_REQD_SHIFT,
DMAC4_CHCFG_n_REQD);
}
else
{
RZA_IO_RegWrite_32(&DMAC4.CHCFG_n,
req_direction,
DMAC4_CHCFG_n_REQD_SHIFT,
DMAC4_CHCFG_n_REQD);
}
RZA_IO_RegWrite_32(&DMAC45.DMARS,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_RID],
DMAC45_DMARS_CH4_RID_SHIFT,
DMAC45_DMARS_CH4_RID);
RZA_IO_RegWrite_32(&DMAC45.DMARS,
usb1_host_dmac_peri_req_init_table[request_factor][DMAC_REQ_MID],
DMAC45_DMARS_CH4_MID_SHIFT,
DMAC45_DMARS_CH4_MID);
/* PR : Round robin mode */
RZA_IO_RegWrite_32(&DMAC07.DCTRL_0_7,
1,
DMAC07_DCTRL_0_7_PR_SHIFT,
DMAC07_DCTRL_0_7_PR);
}
}
/*******************************************************************************
* Function Name: usb1_host_DMAC4_Open
* Description : Enables DMAC channel 4 transfer.
* Arguments : uint32_t req : DMAC request mode
* Return Value : 0 : Succeeded in enabling DMA transfer
* : -1 : Failed to enable DMA transfer (due to DMA operation)
*******************************************************************************/
int32_t usb1_host_DMAC4_Open (uint32_t req)
{
int32_t ret;
volatile uint8_t dummy;
/* Transferable? */
if ((0 == RZA_IO_RegRead_32(&DMAC4.CHSTAT_n,
DMAC4_CHSTAT_n_EN_SHIFT,
DMAC4_CHSTAT_n_EN)) &&
(0 == RZA_IO_RegRead_32(&DMAC4.CHSTAT_n,
DMAC4_CHSTAT_n_TACT_SHIFT,
DMAC4_CHSTAT_n_TACT)))
{
/* Clear Channel Status Register */
RZA_IO_RegWrite_32(&DMAC4.CHCTRL_n,
1,
DMAC4_CHCTRL_n_SWRST_SHIFT,
DMAC4_CHCTRL_n_SWRST);
dummy = RZA_IO_RegRead_32(&DMAC4.CHCTRL_n,
DMAC4_CHCTRL_n_SWRST_SHIFT,
DMAC4_CHCTRL_n_SWRST);
/* Enable DMA transfer */
RZA_IO_RegWrite_32(&DMAC4.CHCTRL_n,
1,
DMAC4_CHCTRL_n_SETEN_SHIFT,
DMAC4_CHCTRL_n_SETEN);
/* ---- Request by software ---- */
if (DMAC_REQ_MODE_SOFT == req)
{
/* DMA transfer Request by software */
RZA_IO_RegWrite_32(&DMAC4.CHCTRL_n,
1,
DMAC4_CHCTRL_n_STG_SHIFT,
DMAC4_CHCTRL_n_STG);
}
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
/*******************************************************************************
* Function Name: usb1_host_DMAC4_Close
* Description : Aborts DMAC channel 4 transfer. Returns the remaining transfer
* : byte count at the time of DMA transfer abort to the argument
* : *remain.
* Arguments : uint32_t * remain : Remaining transfer byte count when
* : : DMA transfer is aborted
* Return Value : none
*******************************************************************************/
void usb1_host_DMAC4_Close (uint32_t * remain)
{
/* ==== Abort transfer ==== */
RZA_IO_RegWrite_32(&DMAC4.CHCTRL_n,
1,
DMAC4_CHCTRL_n_CLREN_SHIFT,
DMAC4_CHCTRL_n_CLREN);
while (1 == RZA_IO_RegRead_32(&DMAC4.CHSTAT_n,
DMAC4_CHSTAT_n_TACT_SHIFT,
DMAC4_CHSTAT_n_TACT))
{
/* Loop until transfer is aborted */
}
while (1 == RZA_IO_RegRead_32(&DMAC4.CHSTAT_n,
DMAC4_CHSTAT_n_EN_SHIFT,
DMAC4_CHSTAT_n_EN))
{
/* Loop until 0 is set in EN before checking the remaining transfer byte count */
}
/* ==== Obtain remaining transfer byte count ==== */
*remain = DMAC4.CRTB_n;
}
/*******************************************************************************
* Function Name: usb1_host_DMAC4_Load_Set
* Description : Sets the transfer source address, transfer destination
* : address, and total transfer byte count respectively
* : specified by the argument src_addr, dst_addr, and count to
* : DMAC channel 4 as DMA transfer information.
* : Sets the register set selected by the CHCFG_n register
* : RSEL bit from the Next0 or Next1 register set.
* : This function should be called when DMA transfer of DMAC
* : channel 4 is aboted.
* Arguments : uint32_t src_addr : Transfer source address
* : uint32_t dst_addr : Transfer destination address
* : uint32_t count : Total transfer byte count
* Return Value : none
*******************************************************************************/
void usb1_host_DMAC4_Load_Set (uint32_t src_addr, uint32_t dst_addr, uint32_t count)
{
uint8_t reg_set;
/* Obtain register set in use */
reg_set = RZA_IO_RegRead_32(&DMAC4.CHSTAT_n,
DMAC4_CHSTAT_n_SR_SHIFT,
DMAC4_CHSTAT_n_SR);
/* ==== Load ==== */
if (0 == reg_set)
{
/* ---- Next0 Register Set ---- */
DMAC4.N0SA_n = src_addr; /* Start address of transfer source */
DMAC4.N0DA_n = dst_addr; /* Start address of transfer destination */
DMAC4.N0TB_n = count; /* Total transfer byte count */
}
else
{
/* ---- Next1 Register Set ---- */
DMAC4.N1SA_n = src_addr; /* Start address of transfer source */
DMAC4.N1DA_n = dst_addr; /* Start address of transfer destination */
DMAC4.N1TB_n = count; /* Total transfer byte count */
}
}
/* End of File */

View file

@ -0,0 +1,778 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name : usb1_host_userdef.c
* $Rev: 1116 $
* $Date:: 2014-07-09 16:29:19 +0900#$
* Device(s) : RZ/A1H
* Tool-Chain :
* OS : None
* H/W Platform :
* Description : RZ/A1H R7S72100 USB Sample Program
* Operation :
* Limitations :
*******************************************************************************/
/*******************************************************************************
Includes <System Includes> , "Project Includes"
*******************************************************************************/
#include <stdio.h>
#include "cmsis_os.h"
#include "r_typedefs.h"
#include "iodefine.h"
#include "devdrv_usb_host_api.h"
#include "usb1_host.h"
#include "MBRZA1H.h" /* INTC Driver Header */
#include "usb1_host_dmacdrv.h"
#include "ohci_wrapp_RZ_A1_local.h"
/*******************************************************************************
Typedef definitions
*******************************************************************************/
/*******************************************************************************
Macro definitions
*******************************************************************************/
#define DUMMY_ACCESS OSTM0CNT
/* #define CACHE_WRITEBACK */
/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
extern int32_t io_cwb(unsigned long start, unsigned long end);
/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
static void usb1_host_enable_dmac0(uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc);
static void usb1_host_enable_dmac1(uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc);
static void Userdef_USB_usb1_host_delay_10us_2(void);
/*******************************************************************************
Private global variables and functions
*******************************************************************************/
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_d0fifo_dmaintid
* Description : get D0FIFO DMA Interrupt ID
* Arguments : none
* Return Value : D0FIFO DMA Interrupt ID
*******************************************************************************/
uint16_t Userdef_USB_usb1_host_d0fifo_dmaintid (void)
{
#if(1) /* ohci_wrapp */
return 0xFFFF;
#else
return DMAINT1_IRQn;
#endif
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_d1fifo_dmaintid
* Description : get D1FIFO DMA Interrupt ID
* Arguments : none
* Return Value : D1FIFO DMA Interrupt ID
*******************************************************************************/
uint16_t Userdef_USB_usb1_host_d1fifo_dmaintid (void)
{
#if(1) /* ohci_wrapp */
return 0xFFFF;
#else
return DMAINT2_IRQn;
#endif
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_attach
* Description : Wait for the software of 1ms.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_attach (void)
{
// printf("\n");
// printf("channel 1 attach device\n");
// printf("\n");
ohciwrapp_loc_Connect(1);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_detach
* Description : Wait for the software of 1ms.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_detach (void)
{
// printf("\n");
// printf("channel 1 detach device\n");
// printf("\n");
ohciwrapp_loc_Connect(0);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_delay_1ms
* Description : Wait for the software of 1ms.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_delay_1ms (void)
{
osDelay(1);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_delay_xms
* Description : Wait for the software in the period of time specified by the
* : argument.
* : Alter this function according to the user's system.
* Arguments : uint32_t msec ; Wait Time (msec)
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_delay_xms (uint32_t msec)
{
osDelay(msec);
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_delay_10us
* Description : Waits for software for the period specified by the argument.
* : Alter this function according to the user's system.
* Arguments : uint32_t usec ; Wait Time(x 10usec)
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_delay_10us (uint32_t usec)
{
volatile int i;
/* Wait 10us (Please change for your MCU) */
for (i = 0; i < usec; ++i)
{
Userdef_USB_usb1_host_delay_10us_2();
}
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_delay_10us_2
* Description : Waits for software for the period specified by the argument.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
static void Userdef_USB_usb1_host_delay_10us_2 (void)
{
volatile int i;
volatile unsigned long tmp;
/* Wait 1us (Please change for your MCU) */
for (i = 0; i < 14; ++i)
{
tmp = DUMMY_ACCESS;
}
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_delay_500ns
* Description : Wait for software for 500ns.
* : Alter this function according to the user's system.
* Arguments : none
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_delay_500ns (void)
{
volatile int i;
volatile unsigned long tmp;
/* Wait 500ns (Please change for your MCU) */
/* Wait 500ns I clock 266MHz */
tmp = DUMMY_ACCESS;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_start_dma
* Description : Enables DMA transfer on the information specified by the argument.
* : Set DMAC register by this function to enable DMA transfer.
* : After executing this function, USB module is set to start DMA
* : transfer. DMA transfer should not wait for DMA transfer complete.
* Arguments : USB_HOST_DMA_t *dma : DMA parameter
* : typedef struct{
* : uint32_t fifo; FIFO for using
* : uint32_t buffer; Start address of transfer source/destination
* : uint32_t bytes; Transfer size(Byte)
* : uint32_t dir; Transfer direction(0:Buffer->FIFO, 1:FIFO->Buffer)
* : uint32_t size; DMA transfer size
* : } USB_HOST_DMA_t;
* : uint16_t dfacc ; 0 : cycle steal mode
* : 1 : 16byte continuous mode
* : 2 : 32byte continuous mode
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_start_dma (USB_HOST_DMA_t * dma, uint16_t dfacc)
{
uint32_t trncount;
uint32_t src;
uint32_t dst;
uint32_t size;
uint32_t dir;
#ifdef CACHE_WRITEBACK
uint32_t ptr;
#endif
trncount = dma->bytes;
dir = dma->dir;
if (dir == USB_HOST_FIFO2BUF)
{
/* DxFIFO determination */
dst = dma->buffer;
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB201.D1FIFO.UINT32);
}
size = dma->size;
if (size == 0)
{
src += 3; /* byte access */
}
else if (size == 1)
{
src += 2; /* short access */
}
else
{
/* Do Nothing */
}
#else
size = dma->size;
if (size == 2)
{
/* 32bit access */
if (dfacc == 2)
{
/* 32byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB201.D0FIFOB0);
}
else
{
src = (uint32_t)(&USB201.D1FIFOB0);
}
}
else if (dfacc == 1)
{
/* 16byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB201.D0FIFOB0);
}
else
{
src = (uint32_t)(&USB201.D1FIFOB0);
}
}
else
{
/* normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB201.D1FIFO.UINT32);
}
}
}
else if (size == 1)
{
/* 16bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB201.D1FIFO.UINT32);
}
src += 2; /* short access */
}
else
{
/* 8bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
src = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
src = (uint32_t)(&USB201.D1FIFO.UINT32);
}
src += 3; /* byte access */
}
#endif
}
else
{
/* DxFIFO determination */
src = dma->buffer;
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB201.D1FIFO.UINT32);
}
size = dma->size;
if (size == 0)
{
dst += 3; /* byte access */
}
else if (size == 1)
{
dst += 2; /* short access */
}
else
{
/* Do Nothing */
}
#else
size = dma->size;
if (size == 2)
{
/* 32bit access */
if (dfacc == 2)
{
/* 32byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB201.D0FIFOB0);
}
else
{
dst = (uint32_t)(&USB201.D1FIFOB0);
}
}
else if (dfacc == 1)
{
/* 16byte access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB201.D0FIFOB0);
}
else
{
dst = (uint32_t)(&USB201.D1FIFOB0);
}
}
else
{
/* normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB201.D1FIFO.UINT32);
}
}
}
else if (size == 1)
{
/* 16bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB201.D1FIFO.UINT32);
}
dst += 2; /* short access */
}
else
{
/* 8bit access */
dfacc = 0; /* force normal access */
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
dst = (uint32_t)(&USB201.D0FIFO.UINT32);
}
else
{
dst = (uint32_t)(&USB201.D1FIFO.UINT32);
}
dst += 3; /* byte access */
}
#endif
}
#ifdef CACHE_WRITEBACK
ptr = (uint32_t)dma->buffer;
if ((ptr & 0x20000000ul) == 0)
{
io_cwb((uint32_t)ptr,(uint32_t)(ptr)+trncount);
}
#endif
if (dma->fifo == USB_HOST_D0FIFO_DMA)
{
usb1_host_enable_dmac0(src, dst, trncount, size, dir, dma->fifo, dfacc);
}
else
{
usb1_host_enable_dmac1(src, dst, trncount, size, dir, dma->fifo, dfacc);
}
}
/*******************************************************************************
* Function Name: usb1_host_enable_dmac0
* Description : Enables DMA transfer on the information specified by the argument.
* Arguments : uint32_t src : src address
* : uint32_t dst : dst address
* : uint32_t count : transfer byte
* : uint32_t size : transfer size
* : uint32_t dir : direction
* : uint32_t fifo : FIFO(D0FIFO or D1FIFO)
* : uint16_t dfacc : 0 : normal access
* : : 1 : 16byte access
* : : 2 : 32byte access
* Return Value : none
*******************************************************************************/
static void usb1_host_enable_dmac0 (uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc)
{
dmac_transinfo_t trans_info;
uint32_t request_factor = 0;
int32_t ret;
/* ==== Variable setting for DMAC initialization ==== */
trans_info.src_addr = (uint32_t)src; /* Start address of transfer source */
trans_info.dst_addr = (uint32_t)dst; /* Start address of transfer destination */
trans_info.count = (uint32_t)count; /* Total byte count to be transferred */
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
#else
if (dfacc == 2)
{
/* 32byte access */
trans_info.src_size = DMAC_TRANS_SIZE_256; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_256; /* Transfer destination transfer size */
}
else if (dfacc == 1)
{
/* 16byte access */
trans_info.src_size = DMAC_TRANS_SIZE_128; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_128; /* Transfer destination transfer size */
}
else
{
/* normal access */
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
}
#endif
if (dir == USB_HOST_FIFO2BUF)
{
request_factor = DMAC_REQ_USB1_DMA0_RX; /* USB_0 channel 0 receive FIFO full */
trans_info.saddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer destination address */
}
else if (dir == USB_HOST_BUF2FIFO)
{
request_factor = DMAC_REQ_USB1_DMA0_TX; /* USB_0 channel 0 receive FIFO empty */
trans_info.saddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer destination address */
}
else
{
/* Do Nothing */
}
/* ==== DMAC initialization ==== */
usb1_host_DMAC3_PeriReqInit((const dmac_transinfo_t *)&trans_info,
DMAC_MODE_REGISTER,
DMAC_SAMPLE_SINGLE,
request_factor,
0); /* Don't care DMAC_REQ_REQD is setting in usb1_host_DMAC3_PeriReqInit() */
/* ==== DMAC startup ==== */
ret = usb1_host_DMAC3_Open(DMAC_REQ_MODE_PERI);
if (ret != 0)
{
// printf("DMAC3 Open error!!\n");
}
return;
}
/*******************************************************************************
* Function Name: usb1_host_enable_dmac1
* Description : Enables DMA transfer on the information specified by the argument.
* Arguments : uint32_t src : src address
* : uint32_t dst : dst address
* : uint32_t count : transfer byte
* : uint32_t size : transfer size
* : uint32_t dir : direction
* : uint32_t fifo : FIFO(D0FIFO or D1FIFO)
* : uint16_t dfacc : 0 : normal access
* : : 1 : 16byte access
* : : 2 : 32byte access
* Return Value : none
*******************************************************************************/
static void usb1_host_enable_dmac1 (uint32_t src, uint32_t dst, uint32_t count,
uint32_t size, uint32_t dir, uint32_t fifo, uint16_t dfacc)
{
dmac_transinfo_t trans_info;
uint32_t request_factor = 0;
int32_t ret;
/* ==== Variable setting for DMAC initialization ==== */
trans_info.src_addr = (uint32_t)src; /* Start address of transfer source */
trans_info.dst_addr = (uint32_t)dst; /* Start address of transfer destination */
trans_info.count = (uint32_t)count; /* Total byte count to be transferred */
#ifndef __USB_HOST_DF_ACC_ENABLE__
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
#else
if (dfacc == 2)
{
/* 32byte access */
trans_info.src_size = DMAC_TRANS_SIZE_256; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_256; /* Transfer destination transfer size */
}
else if (dfacc == 1)
{
/* 16byte access */
trans_info.src_size = DMAC_TRANS_SIZE_128; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_128; /* Transfer destination transfer size */
}
else
{
/* normal access */
if (size == 0)
{
trans_info.src_size = DMAC_TRANS_SIZE_8; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_8; /* Transfer destination transfer size */
}
else if (size == 1)
{
trans_info.src_size = DMAC_TRANS_SIZE_16; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_16; /* Transfer destination transfer size */
}
else if (size == 2)
{
trans_info.src_size = DMAC_TRANS_SIZE_32; /* Transfer source transfer size */
trans_info.dst_size = DMAC_TRANS_SIZE_32; /* Transfer destination transfer size */
}
else
{
// printf("size error!!\n");
}
}
#endif
if (dir == USB_HOST_FIFO2BUF)
{
request_factor =DMAC_REQ_USB1_DMA1_RX; /* USB_0 channel 0 receive FIFO full */
trans_info.saddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer destination address */
}
else if (dir == USB_HOST_BUF2FIFO)
{
request_factor =DMAC_REQ_USB1_DMA1_TX; /* USB_0 channel 0 receive FIFO empty */
trans_info.saddr_dir = DMAC_TRANS_ADR_INC; /* Count direction of transfer source address */
trans_info.daddr_dir = DMAC_TRANS_ADR_NO_INC; /* Count direction of transfer destination address */
}
else
{
/* Do Nothing */
}
/* ==== DMAC initialization ==== */
usb1_host_DMAC4_PeriReqInit((const dmac_transinfo_t *)&trans_info,
DMAC_MODE_REGISTER,
DMAC_SAMPLE_SINGLE,
request_factor,
0); /* Don't care DMAC_REQ_REQD is setting in usb1_host_DMAC4_PeriReqInit() */
/* ==== DMAC startup ==== */
ret = usb1_host_DMAC4_Open(DMAC_REQ_MODE_PERI);
if (ret != 0)
{
// printf("DMAC4 Open error!!\n");
}
return;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_stop_dma0
* Description : Disables DMA transfer.
* Arguments : none
* Return Value : uint32_t return Transfer Counter register(DMATCRn) value
* : regarding to the bus width.
* Notice : This function should be executed to DMAC executed at the time
* : of specification of D0_FIF0_DMA in dma->fifo.
*******************************************************************************/
uint32_t Userdef_USB_usb1_host_stop_dma0 (void)
{
uint32_t remain;
/* ==== DMAC release ==== */
usb1_host_DMAC3_Close(&remain);
return remain;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_stop_dma1
* Description : Disables DMA transfer.
* : This function should be executed to DMAC executed at the time
* : of specification of D1_FIF0_DMA in dma->fifo.
* Arguments : none
* Return Value : uint32_t return Transfer Counter register(DMATCRn) value
* : regarding to the bus width.
*******************************************************************************/
uint32_t Userdef_USB_usb1_host_stop_dma1 (void)
{
uint32_t remain;
/* ==== DMAC release ==== */
usb1_host_DMAC4_Close(&remain);
return remain;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_notice
* Description : Notice of USER
* Arguments : const char *format
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_notice (const char * format)
{
// printf(format);
return;
}
/*******************************************************************************
* Function Name: Userdef_USB_usb1_host_user_rdy
* Description : This function notify a user and wait for trigger
* Arguments : const char *format
* : uint16_t data
* Return Value : none
*******************************************************************************/
void Userdef_USB_usb1_host_user_rdy (const char * format, uint16_t data)
{
// printf(format, data);
getchar();
return;
}
/* End of File */

View file

@ -0,0 +1,100 @@
/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2014 - 2015 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
#ifndef USB_HOST_SETTING_H
#define USB_HOST_SETTING_H
#ifdef __cplusplus
extern "C" {
#endif
#define USB_HOST_CH 0
#define USB_HOST_HISPEED 1
#define INT_TRANS_MAX_NUM 4 /* min:1 max:4 */
#define ISO_TRANS_MAX_NUM 0 /* min:0 max:2 */
#if (USB_HOST_CH == 0)
#include "usb0_host.h"
#define USB20X USB200
#define USBIXUSBIX USBI0_IRQn
#define g_usbx_host_SupportUsbDeviceSpeed g_usb0_host_SupportUsbDeviceSpeed
#define g_usbx_host_UsbDeviceSpeed g_usb0_host_UsbDeviceSpeed
#define g_usbx_host_CmdStage g_usb0_host_CmdStage
#define g_usbx_host_pipe_status g_usb0_host_pipe_status
#define g_usbx_host_data_pointer g_usb0_host_data_pointer
#define g_usbx_host_data_count g_usb0_host_data_count
#define usbx_api_host_init usb0_api_host_init
#define usbx_host_UsbBusReset usb0_host_UsbBusReset
#define usbx_host_get_devadd usb0_host_get_devadd
#define usbx_host_set_devadd usb0_host_set_devadd
#define usbx_host_SetupStage usb0_host_SetupStage
#define usbx_host_CtrlWriteStart usb0_host_CtrlWriteStart
#define usbx_host_CtrlReadStart usb0_host_CtrlReadStart
#define usbx_api_host_SetEndpointTable usb0_api_host_SetEndpointTable
#define usbx_host_start_send_transfer usb0_host_start_send_transfer
#define usbx_host_start_receive_transfer usb0_host_start_receive_transfer
#define usbx_host_stop_transfer usb0_host_stop_transfer
#define usbx_host_set_sqclr usb0_host_set_sqclr
#define usbx_host_set_sqset usb0_host_set_sqset
#define usbx_host_CheckAttach usb0_host_CheckAttach
#define usbx_host_UsbDetach usb0_host_UsbDetach
#define usbx_host_UsbAttach usb0_host_UsbAttach
#define usbx_host_init_pipe_status usb0_host_init_pipe_status
#define usbx_host_get_sqmon usb0_host_get_sqmon
#else
#include "usb1_host.h"
#define USB20X USB201
#define USBIXUSBIX USBI1_IRQn
#define g_usbx_host_SupportUsbDeviceSpeed g_usb1_host_SupportUsbDeviceSpeed
#define g_usbx_host_UsbDeviceSpeed g_usb1_host_UsbDeviceSpeed
#define g_usbx_host_CmdStage g_usb1_host_CmdStage
#define g_usbx_host_pipe_status g_usb1_host_pipe_status
#define g_usbx_host_data_pointer g_usb1_host_data_pointer
#define g_usbx_host_data_count g_usb1_host_data_count
#define usbx_api_host_init usb1_api_host_init
#define usbx_host_UsbBusReset usb1_host_UsbBusReset
#define usbx_host_get_devadd usb1_host_get_devadd
#define usbx_host_set_devadd usb1_host_set_devadd
#define usbx_host_SetupStage usb1_host_SetupStage
#define usbx_host_CtrlWriteStart usb1_host_CtrlWriteStart
#define usbx_host_CtrlReadStart usb1_host_CtrlReadStart
#define usbx_api_host_SetEndpointTable usb1_api_host_SetEndpointTable
#define usbx_host_start_send_transfer usb1_host_start_send_transfer
#define usbx_host_start_receive_transfer usb1_host_start_receive_transfer
#define usbx_host_stop_transfer usb1_host_stop_transfer
#define usbx_host_set_sqclr usb1_host_set_sqclr
#define usbx_host_set_sqset usb1_host_set_sqset
#define usbx_host_CheckAttach usb1_host_CheckAttach
#define usbx_host_UsbDetach usb1_host_UsbDetach
#define usbx_host_UsbAttach usb1_host_UsbAttach
#define usbx_host_init_pipe_status usb1_host_init_pipe_status
#define usbx_host_get_sqmon usb1_host_get_sqmon
#endif
#ifdef __cplusplus
}
#endif
#endif /* USB_HOST_SETTING_H */

View file

@ -0,0 +1,124 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "USBDeviceConnected.h"
#include "dbg.h"
USBDeviceConnected::USBDeviceConnected() {
init();
}
void USBDeviceConnected::init() {
hub_nb = 0;
port = 0;
vid = 0;
pid = 0;
nb_interf = 0;
enumerated = false;
activeAddr = false;
sizeControlEndpoint = 8;
device_class = 0;
device_subclass = 0;
proto = 0;
speed = false;
for (int i = 0; i < MAX_INTF; i++) {
memset((void *)&intf[i], 0, sizeof(INTERFACE));
intf[i].in_use = false;
for (int j = 0; j < MAX_ENDPOINT_PER_INTERFACE; j++) {
intf[i].ep[j] = NULL;
strcpy(intf[i].name, "Unknown");
}
}
hub_parent = NULL;
hub = NULL;
nb_interf = 0;
}
INTERFACE * USBDeviceConnected::getInterface(uint8_t index) {
if (index >= MAX_INTF)
return NULL;
if (intf[index].in_use)
return &intf[index];
return NULL;
}
bool USBDeviceConnected::addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) {
if ((intf_nb >= MAX_INTF) || (intf[intf_nb].in_use)) {
return false;
}
intf[intf_nb].in_use = true;
intf[intf_nb].intf_class = intf_class;
intf[intf_nb].intf_subclass = intf_subclass;
intf[intf_nb].intf_protocol = intf_protocol;
intf[intf_nb].nb_endpoint = 0;
return true;
}
bool USBDeviceConnected::addEndpoint(uint8_t intf_nb, USBEndpoint * ept) {
if ((intf_nb >= MAX_INTF) || (intf[intf_nb].in_use == false) || (intf[intf_nb].nb_endpoint >= MAX_ENDPOINT_PER_INTERFACE)) {
return false;
}
intf[intf_nb].nb_endpoint++;
for (int i = 0; i < MAX_ENDPOINT_PER_INTERFACE; i++) {
if (intf[intf_nb].ep[i] == NULL) {
intf[intf_nb].ep[i] = ept;
return true;
}
}
return false;
}
void USBDeviceConnected::init(uint8_t hub_, uint8_t port_, bool lowSpeed_) {
USB_DBG("init dev: %p", this);
init();
hub_nb = hub_;
port = port_;
speed = lowSpeed_;
}
void USBDeviceConnected::disconnect() {
for(int i = 0; i < MAX_INTF; i++) {
intf[i].detach.call();
}
init();
}
USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index) {
if (intf_nb >= MAX_INTF) {
return NULL;
}
for (int i = 0; i < MAX_ENDPOINT_PER_INTERFACE; i++) {
if ((intf[intf_nb].ep[i]->getType() == type) && (intf[intf_nb].ep[i]->getDir() == dir)) {
if(index) {
index--;
} else {
return intf[intf_nb].ep[i];
}
}
}
return NULL;
}
USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, uint8_t index) {
if ((intf_nb >= MAX_INTF) || (index >= MAX_ENDPOINT_PER_INTERFACE)) {
return NULL;
}
return intf[intf_nb].ep[index];
}

View file

@ -0,0 +1,185 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBDEVICECONNECTED_H
#define USBDEVICECONNECTED_H
#include "stdint.h"
#include "USBEndpoint.h"
#include "USBHostConf.h"
#include "rtos.h"
class USBHostHub;
typedef struct {
bool in_use;
uint8_t nb_endpoint;
uint8_t intf_class;
uint8_t intf_subclass;
uint8_t intf_protocol;
USBEndpoint * ep[MAX_ENDPOINT_PER_INTERFACE];
FunctionPointer detach;
char name[10];
} INTERFACE;
/**
* USBDeviceConnected class
*/
class USBDeviceConnected
{
public:
/**
* Constructor
*/
USBDeviceConnected();
/**
* Attach an USBEndpoint to this device
*
* @param intf_nb interface number
* @param ep pointeur on the USBEndpoint which will be attached
* @returns true if successful, false otherwise
*/
bool addEndpoint(uint8_t intf_nb, USBEndpoint * ep);
/**
* Retrieve an USBEndpoint by its TYPE and DIRECTION
*
* @param intf_nb the interface on which to lookup the USBEndpoint
* @param type type of the USBEndpoint looked for
* @param dir direction of the USBEndpoint looked for
* @param index the index of the USBEndpoint whitin the interface
* @returns pointer on the USBEndpoint if found, NULL otherwise
*/
USBEndpoint * getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index = 0);
/**
* Retrieve an USBEndpoint by its index
*
* @param intf_nb interface number
* @param index index of the USBEndpoint
* @returns pointer on the USBEndpoint if found, NULL otherwise
*/
USBEndpoint * getEndpoint(uint8_t intf_nb, uint8_t index);
/**
* Add a new interface to this device
*
* @param intf_nb interface number
* @param intf_class interface class
* @param intf_subclass interface subclass
* @param intf_protocol interface protocol
* @returns true if successful, false otherwise
*/
bool addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol);
/**
* Get a specific interface
*
* @param index index of the interface to be fetched
* @returns interface
*/
INTERFACE * getInterface(uint8_t index);
/**
* Attach a member function to call when a the device has been disconnected
*
* @param intf_nb interface number
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
*/
template<typename T>
inline void onDisconnect(uint8_t intf_nb, T* tptr, void (T::*mptr)(void)) {
if ((mptr != NULL) && (tptr != NULL)) {
intf[intf_nb].detach.attach(tptr, mptr);
}
}
/**
* Attach a callback called when the device has been disconnected
*
* @param intf_nb interface number
* @param fn function pointer
*/
inline void onDisconnect(uint8_t intf_nb, void (*fn)(void)) {
if (fn != NULL) {
intf[intf_nb].detach.attach(fn);
}
}
/**
* Disconnect the device by calling a callback function registered by a driver
*/
void disconnect();
// setters
void init(uint8_t hub, uint8_t port, bool lowSpeed);
inline void setAddress(uint8_t addr_) { addr = addr_; };
inline void setVid(uint16_t vid_) { vid = vid_; };
inline void setPid(uint16_t pid_) { pid = pid_; };
inline void setClass(uint8_t device_class_) { device_class = device_class_; };
inline void setSubClass(uint8_t device_subclass_) { device_subclass = device_subclass_; };
inline void setProtocol(uint8_t pr) { proto = pr; };
inline void setSizeControlEndpoint(uint32_t size) { sizeControlEndpoint = size; };
inline void activeAddress(bool active) { activeAddr = active; };
inline void setEnumerated() { enumerated = true; };
inline void setNbIntf(uint8_t nb_intf) {nb_interf = nb_intf; };
inline void setHubParent(USBHostHub * hub) { hub_parent = hub; };
inline void setName(const char * name_, uint8_t intf_nb) { strcpy(intf[intf_nb].name, name_); };
//getters
inline uint8_t getPort() { return port; };
inline uint8_t getHub() { return hub_nb; };
inline uint8_t getAddress() { return addr; };
inline uint16_t getVid() { return vid; };
inline uint16_t getPid() { return pid; };
inline uint8_t getClass() { return device_class; };
inline uint8_t getSubClass() { return device_subclass; };
inline uint8_t getProtocol() { return proto; };
inline bool getSpeed() { return speed; };
inline uint32_t getSizeControlEndpoint() { return sizeControlEndpoint; };
inline bool isActiveAddress() { return activeAddr; };
inline bool isEnumerated() { return enumerated; };
inline USBHostHub * getHubParent() { return hub_parent; };
inline uint8_t getNbIntf() { return nb_interf; };
inline const char * getName(uint8_t intf_nb) { return intf[intf_nb].name; };
// in case this device is a hub
USBHostHub * hub;
private:
USBHostHub * hub_parent;
INTERFACE intf[MAX_INTF];
uint32_t sizeControlEndpoint;
uint8_t hub_nb;
uint8_t port;
uint16_t vid;
uint16_t pid;
uint8_t addr;
uint8_t device_class;
uint8_t device_subclass;
uint8_t proto;
bool speed;
volatile bool activeAddr;
volatile bool enumerated;
uint8_t nb_interf;
void init();
};
#endif

View file

@ -0,0 +1,162 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dbg.h"
#include "USBEndpoint.h"
void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2])
{
hced = hced_;
type = type_;
dir = dir_;
setup = (type == CONTROL_ENDPOINT) ? true : false;
//TDs have been allocated by the host
memcpy((HCTD**)td_list, td_list_, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
memset(td_list_[0], 0, sizeof(HCTD));
memset(td_list_[1], 0, sizeof(HCTD));
td_list[0]->ep = this;
td_list[1]->ep = this;
hced->control = 0;
//Empty queue
hced->tailTD = td_list[0];
hced->headTD = td_list[0];
hced->nextED = 0;
address = (ep_number & 0x7F) | ((dir - 1) << 7);
hced->control = ((ep_number & 0x7F) << 7) // Endpoint address
| (type != CONTROL_ENDPOINT ? ( dir << 11) : 0 ) // direction : Out = 1, 2 = In
| ((size & 0x3ff) << 16); // MaxPkt Size
transfer_len = 0;
transferred = 0;
buf_start = 0;
nextEp = NULL;
td_current = td_list[0];
td_next = td_list[1];
intf_nb = 0;
state = USB_TYPE_IDLE;
}
void USBEndpoint::setSize(uint32_t size)
{
hced->control &= ~(0x3ff << 16);
hced->control |= (size << 16);
}
void USBEndpoint::setDeviceAddress(uint8_t addr)
{
hced->control &= ~(0x7f);
hced->control |= (addr & 0x7F);
}
void USBEndpoint::setSpeed(uint8_t speed)
{
hced->control &= ~(1 << 13);
hced->control |= (speed << 13);
}
//Only for control Eps
void USBEndpoint::setNextToken(uint32_t token)
{
switch (token) {
case TD_SETUP:
dir = OUT;
setup = true;
break;
case TD_IN:
dir = IN;
setup = false;
break;
case TD_OUT:
dir = OUT;
setup = false;
break;
}
}
struct {
USB_TYPE type;
const char * str;
} static type_string[] = {
/*0*/ {USB_TYPE_OK, "USB_TYPE_OK"},
{USB_TYPE_CRC_ERROR, "USB_TYPE_CRC_ERROR"},
{USB_TYPE_BIT_STUFFING_ERROR, "USB_TYPE_BIT_STUFFING_ERROR"},
{USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR, "USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR"},
{USB_TYPE_STALL_ERROR, "USB_TYPE_STALL_ERROR"},
/*5*/ {USB_TYPE_DEVICE_NOT_RESPONDING_ERROR, "USB_TYPE_DEVICE_NOT_RESPONDING_ERROR"},
{USB_TYPE_PID_CHECK_FAILURE_ERROR, "USB_TYPE_PID_CHECK_FAILURE_ERROR"},
{USB_TYPE_UNEXPECTED_PID_ERROR, "USB_TYPE_UNEXPECTED_PID_ERROR"},
{USB_TYPE_DATA_OVERRUN_ERROR, "USB_TYPE_DATA_OVERRUN_ERROR"},
{USB_TYPE_DATA_UNDERRUN_ERROR, "USB_TYPE_DATA_UNDERRUN_ERROR"},
/*10*/ {USB_TYPE_ERROR, "USB_TYPE_ERROR"},
{USB_TYPE_ERROR, "USB_TYPE_ERROR"},
{USB_TYPE_BUFFER_OVERRUN_ERROR, "USB_TYPE_BUFFER_OVERRUN_ERROR"},
{USB_TYPE_BUFFER_UNDERRUN_ERROR, "USB_TYPE_BUFFER_UNDERRUN_ERROR"},
{USB_TYPE_DISCONNECTED, "USB_TYPE_DISCONNECTED"},
/*15*/ {USB_TYPE_FREE, "USB_TYPE_FREE"},
{USB_TYPE_IDLE, "USB_TYPE_IDLE"},
{USB_TYPE_PROCESSING, "USB_TYPE_PROCESSING"},
{USB_TYPE_ERROR, "USB_TYPE_ERROR"}
};
void USBEndpoint::setState(uint8_t st) {
if (st > 18)
return;
state = type_string[st].type;
}
const char * USBEndpoint::getStateString() {
return type_string[state].str;
}
void USBEndpoint::queueTransfer()
{
transfer_len = (uint32_t)td_current->bufEnd - (uint32_t)td_current->currBufPtr + 1;
transferred = transfer_len;
buf_start = (uint8_t *)td_current->currBufPtr;
//Now add this free TD at this end of the queue
state = USB_TYPE_PROCESSING;
td_current->nextTD = td_next;
hced->tailTD = td_next;
}
void USBEndpoint::unqueueTransfer(volatile HCTD * td)
{
td->control=0;
td->currBufPtr=0;
td->bufEnd=0;
td->nextTD=0;
hced->headTD = (HCTD *)((uint32_t)hced->tailTD | ((uint32_t)hced->headTD & 0x2)); //Carry bit
td_current = td_next;
td_next = td;
}
void USBEndpoint::queueEndpoint(USBEndpoint * ed)
{
nextEp = ed;
hced->nextED = (ed == NULL) ? 0 : ed->getHCED();
}

View file

@ -0,0 +1,171 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBENDPOINT_H
#define USBENDPOINT_H
#include "FunctionPointer.h"
#include "USBHostTypes.h"
#include "rtos.h"
class USBDeviceConnected;
/**
* USBEndpoint class
*/
class USBEndpoint
{
public:
/**
* Constructor
*/
USBEndpoint() {
state = USB_TYPE_FREE;
nextEp = NULL;
};
/**
* Initialize an endpoint
*
* @param hced hced associated to the endpoint
* @param type endpoint type
* @param dir endpoint direction
* @param size endpoint size
* @param ep_number endpoint number
* @param td_list array of two allocated transfer descriptors
*/
void init(HCED * hced, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t ep_number, HCTD* td_list[2]);
/**
* Set next token. Warning: only useful for the control endpoint
*
* @param token IN, OUT or SETUP token
*/
void setNextToken(uint32_t token);
/**
* Queue an endpoint
*
* @param endpoint endpoint which will be queued in the linked list
*/
void queueEndpoint(USBEndpoint * endpoint);
/**
* Queue a transfer on the endpoint
*/
void queueTransfer();
/**
* Unqueue a transfer from the endpoint
*
* @param td hctd which will be unqueued
*/
void unqueueTransfer(volatile HCTD * td);
/**
* Attach a member function to call when a transfer is finished
*
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
*/
template<typename T>
inline void attach(T* tptr, void (T::*mptr)(void)) {
if((mptr != NULL) && (tptr != NULL)) {
rx.attach(tptr, mptr);
}
}
/**
* Attach a callback called when a transfer is finished
*
* @param fptr function pointer
*/
inline void attach(void (*fptr)(void)) {
if(fptr != NULL) {
rx.attach(fptr);
}
}
/**
* Call the handler associted to the end of a transfer
*/
inline void call() {
rx.call();
};
// setters
inline void setState(USB_TYPE st) { state = st; }
void setState(uint8_t st);
void setDeviceAddress(uint8_t addr);
inline void setLengthTransferred(int len) { transferred = len; };
void setSpeed(uint8_t speed);
void setSize(uint32_t size);
inline void setDir(ENDPOINT_DIRECTION d) { dir = d; }
inline void setIntfNb(uint8_t intf_nb_) { intf_nb = intf_nb_; };
// getters
const char * getStateString();
inline USB_TYPE getState() { return state; }
inline ENDPOINT_TYPE getType() { return type; };
inline uint8_t getDeviceAddress() { return hced->control & 0x7f; };
inline int getLengthTransferred() { return transferred; }
inline uint8_t * getBufStart() { return buf_start; }
inline uint8_t getAddress(){ return address; };
inline uint32_t getSize() { return (hced->control >> 16) & 0x3ff; };
inline volatile HCTD * getHeadTD() { return (volatile HCTD*) ((uint32_t)hced->headTD & ~0xF); };
inline volatile HCTD** getTDList() { return td_list; };
inline volatile HCED * getHCED() { return hced; };
inline ENDPOINT_DIRECTION getDir() { return dir; }
inline volatile HCTD * getProcessedTD() { return td_current; };
inline volatile HCTD* getNextTD() { return td_current; };
inline bool isSetup() { return setup; }
inline USBEndpoint * nextEndpoint() { return (USBEndpoint*)nextEp; };
inline uint8_t getIntfNb() { return intf_nb; };
USBDeviceConnected * dev;
Queue<uint8_t, 1> ep_queue;
private:
ENDPOINT_TYPE type;
volatile USB_TYPE state;
ENDPOINT_DIRECTION dir;
bool setup;
uint8_t address;
int transfer_len;
int transferred;
uint8_t * buf_start;
FunctionPointer rx;
USBEndpoint* nextEp;
// USBEndpoint descriptor
volatile HCED * hced;
volatile HCTD * td_list[2];
volatile HCTD * td_current;
volatile HCTD * td_next;
uint8_t intf_nb;
};
#endif

View file

@ -0,0 +1,169 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHALHOST_H
#define USBHALHOST_H
#include "USBHostTypes.h"
#include "USBHostConf.h"
class USBHostHub;
/**
* USBHALHost class
*/
class USBHALHost {
protected:
/**
* Constructor
* init variables and memory where will be stored HCCA, ED and TD
*/
USBHALHost();
/**
* Initialize host controller. Enable USB interrupts. This part is not in the constructor because,
* this function calls a virtual method if a device is already connected
*/
void init();
/**
* reset the root hub
*/
void resetRootHub();
/**
* return the value contained in the control HEAD ED register
*
* @returns address of the control Head ED
*/
uint32_t controlHeadED();
/**
* return the value contained in the bulk HEAD ED register
*
* @returns address of the bulk head ED
*/
uint32_t bulkHeadED();
/**
* return the value of the head interrupt ED contained in the HCCA
*
* @returns address of the head interrupt ED contained in the HCCA
*/
uint32_t interruptHeadED();
/**
* Update the head ED for control transfers
*/
void updateControlHeadED(uint32_t addr);
/**
* Update the head ED for bulk transfers
*/
void updateBulkHeadED(uint32_t addr);
/**
* Update the head ED for interrupt transfers
*/
void updateInterruptHeadED(uint32_t addr);
/**
* Enable List for the specified endpoint type
*
* @param type enable the list of ENDPOINT_TYPE type
*/
void enableList(ENDPOINT_TYPE type);
/**
* Disable List for the specified endpoint type
*
* @param type disable the list of ENDPOINT_TYPE type
*/
bool disableList(ENDPOINT_TYPE type);
/**
* Virtual method called when a device has been connected
*
* @param hub hub number of the device
* @param port port number of the device
* @param lowSpeed 1 if low speed, 0 otherwise
* @param hub_parent reference to the hub where the device is connected (NULL if the hub parent is the root hub)
*/
virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL) = 0;
/**
* Virtual method called when a device has been disconnected
*
* @param hub hub number of the device
* @param port port number of the device
* @param hub_parent reference to the hub where the device is connected (NULL if the hub parent is the root hub)
* @param addr list of the TDs which have been completed to dequeue freed TDs
*/
virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr) = 0;
/**
* Virtual method called when a transfer has been completed
*
* @param addr list of the TDs which have been completed
*/
virtual void transferCompleted(volatile uint32_t addr) = 0;
/**
* Find a memory section for a new ED
*
* @returns the address of the new ED
*/
volatile uint8_t * getED();
/**
* Find a memory section for a new TD
*
* @returns the address of the new TD
*/
volatile uint8_t * getTD();
/**
* Release a previous memory section reserved for an ED
*
* @param ed address of the ED
*/
void freeED(volatile uint8_t * ed);
/**
* Release a previous memory section reserved for an TD
*
* @param td address of the TD
*/
void freeTD(volatile uint8_t * td);
private:
static void _usbisr(void);
void UsbIrqhandler();
void memInit();
HCCA volatile * usb_hcca; //256 bytes aligned
uint8_t volatile * usb_edBuf; //4 bytes aligned
uint8_t volatile * usb_tdBuf; //4 bytes aligned
static USBHALHost * instHost;
bool volatile edBufAlloc[MAX_ENDPOINT];
bool volatile tdBufAlloc[MAX_TD];
};
#endif

View file

@ -0,0 +1,325 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(TARGET_LPC1768)
#include "mbed.h"
#include "USBHALHost.h"
#include "dbg.h"
// bits of the USB/OTG clock control register
#define HOST_CLK_EN (1<<0)
#define DEV_CLK_EN (1<<1)
#define PORTSEL_CLK_EN (1<<3)
#define AHB_CLK_EN (1<<4)
// bits of the USB/OTG clock status register
#define HOST_CLK_ON (1<<0)
#define DEV_CLK_ON (1<<1)
#define PORTSEL_CLK_ON (1<<3)
#define AHB_CLK_ON (1<<4)
// we need host clock, OTG/portsel clock and AHB clock
#define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
#define HCCA_SIZE sizeof(HCCA)
#define ED_SIZE sizeof(HCED)
#define TD_SIZE sizeof(HCTD)
#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
static volatile uint8_t usb_buf[TOTAL_SIZE] __attribute((section("AHBSRAM1"),aligned(256))); //256 bytes aligned!
USBHALHost * USBHALHost::instHost;
USBHALHost::USBHALHost() {
instHost = this;
memInit();
memset((void*)usb_hcca, 0, HCCA_SIZE);
for (int i = 0; i < MAX_ENDPOINT; i++) {
edBufAlloc[i] = false;
}
for (int i = 0; i < MAX_TD; i++) {
tdBufAlloc[i] = false;
}
}
void USBHALHost::init() {
NVIC_DisableIRQ(USB_IRQn);
//Cut power
LPC_SC->PCONP &= ~(1UL<<31);
wait_ms(100);
// turn on power for USB
LPC_SC->PCONP |= (1UL<<31);
// Enable USB host clock, port selection and AHB clock
LPC_USB->USBClkCtrl |= CLOCK_MASK;
// Wait for clocks to become available
while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK);
// it seems the bits[0:1] mean the following
// 0: U1=device, U2=host
// 1: U1=host, U2=host
// 2: reserved
// 3: U1=host, U2=device
// NB: this register is only available if OTG clock (aka "port select") is enabled!!
// since we don't care about port 2, set just bit 0 to 1 (U1=host)
LPC_USB->OTGStCtrl |= 1;
// now that we've configured the ports, we can turn off the portsel clock
LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
// configure USB D+/D- pins
// P0[29] = USB_D+, 01
// P0[30] = USB_D-, 01
LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
LPC_PINCON->PINSEL1 |= ((1<<26) | (1<<28));
LPC_USB->HcControl = 0; // HARDWARE RESET
LPC_USB->HcControlHeadED = 0; // Initialize Control list head to Zero
LPC_USB->HcBulkHeadED = 0; // Initialize Bulk list head to Zero
// Wait 100 ms before apply reset
wait_ms(100);
// software reset
LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
// Write Fm Interval and Largest Data Packet Counter
LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL;
LPC_USB->HcPeriodicStart = FI * 90 / 100;
// Put HC in operational state
LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
// Set Global Power
LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC;
LPC_USB->HcHCCA = (uint32_t)(usb_hcca);
// Clear Interrrupt Status
LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;
LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC;
// Enable the USB Interrupt
NVIC_SetVector(USB_IRQn, (uint32_t)(_usbisr));
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
NVIC_EnableIRQ(USB_IRQn);
// Check for any connected devices
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
//Device connected
wait_ms(150);
USB_DBG("Device connected (%08x)\n\r", LPC_USB->HcRhPortStatus1);
deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
}
}
uint32_t USBHALHost::controlHeadED() {
return LPC_USB->HcControlHeadED;
}
uint32_t USBHALHost::bulkHeadED() {
return LPC_USB->HcBulkHeadED;
}
uint32_t USBHALHost::interruptHeadED() {
return usb_hcca->IntTable[0];
}
void USBHALHost::updateBulkHeadED(uint32_t addr) {
LPC_USB->HcBulkHeadED = addr;
}
void USBHALHost::updateControlHeadED(uint32_t addr) {
LPC_USB->HcControlHeadED = addr;
}
void USBHALHost::updateInterruptHeadED(uint32_t addr) {
usb_hcca->IntTable[0] = addr;
}
void USBHALHost::enableList(ENDPOINT_TYPE type) {
switch(type) {
case CONTROL_ENDPOINT:
LPC_USB->HcCommandStatus = OR_CMD_STATUS_CLF;
LPC_USB->HcControl |= OR_CONTROL_CLE;
break;
case ISOCHRONOUS_ENDPOINT:
break;
case BULK_ENDPOINT:
LPC_USB->HcCommandStatus = OR_CMD_STATUS_BLF;
LPC_USB->HcControl |= OR_CONTROL_BLE;
break;
case INTERRUPT_ENDPOINT:
LPC_USB->HcControl |= OR_CONTROL_PLE;
break;
}
}
bool USBHALHost::disableList(ENDPOINT_TYPE type) {
switch(type) {
case CONTROL_ENDPOINT:
if(LPC_USB->HcControl & OR_CONTROL_CLE) {
LPC_USB->HcControl &= ~OR_CONTROL_CLE;
return true;
}
return false;
case ISOCHRONOUS_ENDPOINT:
return false;
case BULK_ENDPOINT:
if(LPC_USB->HcControl & OR_CONTROL_BLE){
LPC_USB->HcControl &= ~OR_CONTROL_BLE;
return true;
}
return false;
case INTERRUPT_ENDPOINT:
if(LPC_USB->HcControl & OR_CONTROL_PLE) {
LPC_USB->HcControl &= ~OR_CONTROL_PLE;
return true;
}
return false;
}
return false;
}
void USBHALHost::memInit() {
usb_hcca = (volatile HCCA *)usb_buf;
usb_edBuf = usb_buf + HCCA_SIZE;
usb_tdBuf = usb_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE);
}
volatile uint8_t * USBHALHost::getED() {
for (int i = 0; i < MAX_ENDPOINT; i++) {
if ( !edBufAlloc[i] ) {
edBufAlloc[i] = true;
return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
}
}
perror("Could not allocate ED\r\n");
return NULL; //Could not alloc ED
}
volatile uint8_t * USBHALHost::getTD() {
int i;
for (i = 0; i < MAX_TD; i++) {
if ( !tdBufAlloc[i] ) {
tdBufAlloc[i] = true;
return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
}
}
perror("Could not allocate TD\r\n");
return NULL; //Could not alloc TD
}
void USBHALHost::freeED(volatile uint8_t * ed) {
int i;
i = (ed - usb_edBuf) / ED_SIZE;
edBufAlloc[i] = false;
}
void USBHALHost::freeTD(volatile uint8_t * td) {
int i;
i = (td - usb_tdBuf) / TD_SIZE;
tdBufAlloc[i] = false;
}
void USBHALHost::resetRootHub() {
// Initiate port reset
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS;
while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS);
// ...and clear port reset signal
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
}
void USBHALHost::_usbisr(void) {
if (instHost) {
instHost->UsbIrqhandler();
}
}
void USBHALHost::UsbIrqhandler() {
if( LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable ) //Is there something to actually process?
{
uint32_t int_status = LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable;
// Root hub status change interrupt
if (int_status & OR_INTR_STATUS_RHSC) {
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
// When DRWE is on, Connect Status Change
// means a remote wakeup event.
} else {
//Root device connected
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
// wait 150ms to avoid bounce
wait_ms(150);
//Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
deviceConnected(0, 1, LPC_USB->HcRhPortStatus1 & OR_RH_PORT_LSDA);
}
//Root device disconnected
else {
if (!(int_status & OR_INTR_STATUS_WDH)) {
usb_hcca->DoneHead = 0;
}
// wait 200ms to avoid bounce
wait_ms(200);
deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
if (int_status & OR_INTR_STATUS_WDH) {
usb_hcca->DoneHead = 0;
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
}
}
}
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
}
if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
}
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_RHSC;
}
// Writeback Done Head interrupt
if (int_status & OR_INTR_STATUS_WDH) {
transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE);
LPC_USB->HcInterruptStatus = OR_INTR_STATUS_WDH;
}
}
}
#endif

View file

@ -0,0 +1,292 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(TARGET_RZ_A1H)
#include "mbed.h"
#include "USBHALHost.h"
#include "dbg.h"
#include "ohci_wrapp_RZ_A1.h"
#define HCCA_SIZE sizeof(HCCA)
#define ED_SIZE sizeof(HCED)
#define TD_SIZE sizeof(HCTD)
#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE))
#define ALIGNE_MSK (0x0000000F)
static volatile uint8_t usb_buf[TOTAL_SIZE + ALIGNE_MSK]; //16 bytes aligned!
USBHALHost * USBHALHost::instHost;
USBHALHost::USBHALHost() {
instHost = this;
memInit();
memset((void*)usb_hcca, 0, HCCA_SIZE);
for (int i = 0; i < MAX_ENDPOINT; i++) {
edBufAlloc[i] = false;
}
for (int i = 0; i < MAX_TD; i++) {
tdBufAlloc[i] = false;
}
}
void USBHALHost::init() {
ohciwrapp_init(&_usbisr);
ohciwrapp_reg_w(OHCI_REG_CONTROL, 1); // HARDWARE RESET
ohciwrapp_reg_w(OHCI_REG_CONTROLHEADED, 0); // Initialize Control list head to Zero
ohciwrapp_reg_w(OHCI_REG_BULKHEADED, 0); // Initialize Bulk list head to Zero
// Wait 100 ms before apply reset
wait_ms(100);
// software reset
ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_HCR);
// Write Fm Interval and Largest Data Packet Counter
ohciwrapp_reg_w(OHCI_REG_FMINTERVAL, DEFAULT_FMINTERVAL);
ohciwrapp_reg_w(OHCI_REG_PERIODICSTART, FI * 90 / 100);
// Put HC in operational state
ohciwrapp_reg_w(OHCI_REG_CONTROL, (ohciwrapp_reg_r(OHCI_REG_CONTROL) & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER);
// Set Global Power
ohciwrapp_reg_w(OHCI_REG_RHSTATUS, OR_RH_STATUS_LPSC);
ohciwrapp_reg_w(OHCI_REG_HCCA, (uint32_t)(usb_hcca));
// Clear Interrrupt Status
ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, ohciwrapp_reg_r(OHCI_REG_INTERRUPTSTATUS));
ohciwrapp_reg_w(OHCI_REG_INTERRUPTENABLE, OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC);
// Enable the USB Interrupt
ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_CSC);
ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC);
// Check for any connected devices
if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CCS) {
//Device connected
wait_ms(150);
USB_DBG("Device connected (%08x)\n\r", ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1));
deviceConnected(0, 1, ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_LSDA);
}
}
uint32_t USBHALHost::controlHeadED() {
return ohciwrapp_reg_r(OHCI_REG_CONTROLHEADED);
}
uint32_t USBHALHost::bulkHeadED() {
return ohciwrapp_reg_r(OHCI_REG_BULKHEADED);
}
uint32_t USBHALHost::interruptHeadED() {
return usb_hcca->IntTable[0];
}
void USBHALHost::updateBulkHeadED(uint32_t addr) {
ohciwrapp_reg_w(OHCI_REG_BULKHEADED, addr);
}
void USBHALHost::updateControlHeadED(uint32_t addr) {
ohciwrapp_reg_w(OHCI_REG_CONTROLHEADED, addr);
}
void USBHALHost::updateInterruptHeadED(uint32_t addr) {
usb_hcca->IntTable[0] = addr;
}
void USBHALHost::enableList(ENDPOINT_TYPE type) {
uint32_t wk_data;
switch(type) {
case CONTROL_ENDPOINT:
ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_CLF);
wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_CLE);
ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
break;
case ISOCHRONOUS_ENDPOINT:
break;
case BULK_ENDPOINT:
ohciwrapp_reg_w(OHCI_REG_COMMANDSTATUS, OR_CMD_STATUS_BLF);
wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_BLE);
ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
break;
case INTERRUPT_ENDPOINT:
wk_data = (ohciwrapp_reg_r(OHCI_REG_CONTROL) | OR_CONTROL_PLE);
ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
break;
}
}
bool USBHALHost::disableList(ENDPOINT_TYPE type) {
uint32_t wk_data;
switch(type) {
case CONTROL_ENDPOINT:
wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL);
if(wk_data & OR_CONTROL_CLE) {
wk_data &= ~OR_CONTROL_CLE;
ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
return true;
}
return false;
case ISOCHRONOUS_ENDPOINT:
return false;
case BULK_ENDPOINT:
wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL);
if(wk_data & OR_CONTROL_BLE) {
wk_data &= ~OR_CONTROL_BLE;
ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
return true;
}
return false;
case INTERRUPT_ENDPOINT:
wk_data = ohciwrapp_reg_r(OHCI_REG_CONTROL);
if(wk_data & OR_CONTROL_PLE) {
wk_data &= ~OR_CONTROL_PLE;
ohciwrapp_reg_w(OHCI_REG_CONTROL, wk_data);
return true;
}
return false;
}
return false;
}
void USBHALHost::memInit() {
volatile uint8_t *p_wk_buf = (uint8_t *)(((uint32_t)usb_buf + ALIGNE_MSK) & ~ALIGNE_MSK);
usb_hcca = (volatile HCCA *)p_wk_buf;
usb_edBuf = (volatile uint8_t *)(p_wk_buf + HCCA_SIZE);
usb_tdBuf = (volatile uint8_t *)(p_wk_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE));
}
volatile uint8_t * USBHALHost::getED() {
for (int i = 0; i < MAX_ENDPOINT; i++) {
if ( !edBufAlloc[i] ) {
edBufAlloc[i] = true;
return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE);
}
}
perror("Could not allocate ED\r\n");
return NULL; //Could not alloc ED
}
volatile uint8_t * USBHALHost::getTD() {
int i;
for (i = 0; i < MAX_TD; i++) {
if ( !tdBufAlloc[i] ) {
tdBufAlloc[i] = true;
return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE);
}
}
perror("Could not allocate TD\r\n");
return NULL; //Could not alloc TD
}
void USBHALHost::freeED(volatile uint8_t * ed) {
int i;
i = (ed - usb_edBuf) / ED_SIZE;
edBufAlloc[i] = false;
}
void USBHALHost::freeTD(volatile uint8_t * td) {
int i;
i = (td - usb_tdBuf) / TD_SIZE;
tdBufAlloc[i] = false;
}
void USBHALHost::resetRootHub() {
// Initiate port reset
ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRS);
while (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_PRS);
// ...and clear port reset signal
ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC);
}
void USBHALHost::_usbisr(void) {
if (instHost) {
instHost->UsbIrqhandler();
}
}
void USBHALHost::UsbIrqhandler() {
uint32_t int_status = ohciwrapp_reg_r(OHCI_REG_INTERRUPTSTATUS) & ohciwrapp_reg_r(OHCI_REG_INTERRUPTENABLE);
uint32_t data;
if (int_status != 0) { //Is there something to actually process?
// Root hub status change interrupt
if (int_status & OR_INTR_STATUS_RHSC) {
if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CSC) {
if (ohciwrapp_reg_r(OHCI_REG_RHSTATUS) & OR_RH_STATUS_DRWE) {
// When DRWE is on, Connect Status Change
// means a remote wakeup event.
} else {
//Root device connected
if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_CCS) {
// wait 150ms to avoid bounce
wait_ms(150);
//Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed
data = ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_LSDA;
deviceConnected(0, 1, data);
}
//Root device disconnected
else {
if (!(int_status & OR_INTR_STATUS_WDH)) {
usb_hcca->DoneHead = 0;
}
deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE);
if (int_status & OR_INTR_STATUS_WDH) {
usb_hcca->DoneHead = 0;
ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_WDH);
}
}
}
ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_CSC);
}
if (ohciwrapp_reg_r(OHCI_REG_RHPORTSTATUS1) & OR_RH_PORT_PRSC) {
ohciwrapp_reg_w(OHCI_REG_RHPORTSTATUS1, OR_RH_PORT_PRSC);
}
ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_RHSC);
}
// Writeback Done Head interrupt
if (int_status & OR_INTR_STATUS_WDH) {
transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE);
ohciwrapp_reg_w(OHCI_REG_INTERRUPTSTATUS, OR_INTR_STATUS_WDH);
}
}
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,395 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOST_H
#define USBHOST_H
#include "USBHALHost.h"
#include "USBDeviceConnected.h"
#include "IUSBEnumerator.h"
#include "USBHostConf.h"
#include "rtos.h"
#include "dbg.h"
#include "USBHostHub.h"
/**
* USBHost class
* This class is a singleton. All drivers have a reference on the static USBHost instance
*/
class USBHost : public USBHALHost {
public:
/**
* Static method to create or retrieve the single USBHost instance
*/
static USBHost * getHostInst();
/**
* Control read: setup stage, data stage and status stage
*
* @param dev the control read will be done for this device
* @param requestType request type
* @param request request
* @param value value
* @param index index
* @param buf pointer on a buffer where will be store the data received
* @param len length of the transfer
*
* @returns status of the control read
*/
USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
/**
* Control write: setup stage, data stage and status stage
*
* @param dev the control write will be done for this device
* @param requestType request type
* @param request request
* @param value value
* @param index index
* @param buf pointer on a buffer which will be written
* @param len length of the transfer
*
* @returns status of the control write
*/
USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
/**
* Bulk read
*
* @param dev the bulk transfer will be done for this device
* @param ep USBEndpoint which will be used to read a packet
* @param buf pointer on a buffer where will be store the data received
* @param len length of the transfer
* @param blocking if true, the read is blocking (wait for completion)
*
* @returns status of the bulk read
*/
USB_TYPE bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
/**
* Bulk write
*
* @param dev the bulk transfer will be done for this device
* @param ep USBEndpoint which will be used to write a packet
* @param buf pointer on a buffer which will be written
* @param len length of the transfer
* @param blocking if true, the write is blocking (wait for completion)
*
* @returns status of the bulk write
*/
USB_TYPE bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
/**
* Interrupt read
*
* @param dev the bulk transfer will be done for this device
* @param ep USBEndpoint which will be used to write a packet
* @param buf pointer on a buffer which will be written
* @param len length of the transfer
* @param blocking if true, the read is blocking (wait for completion)
*
* @returns status of the interrupt read
*/
USB_TYPE interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
/**
* Interrupt write
*
* @param dev the bulk transfer will be done for this device
* @param ep USBEndpoint which will be used to write a packet
* @param buf pointer on a buffer which will be written
* @param len length of the transfer
* @param blocking if true, the write is blocking (wait for completion)
*
* @returns status of the interrupt write
*/
USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
/**
* Enumerate a device.
*
* @param dev device which will be enumerated
*
* @returns status of the enumeration
*/
USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator);
/**
* reset a specific device
*
* @param dev device which will be resetted
*/
USB_TYPE resetDevice(USBDeviceConnected * dev);
/**
* Get a device
*
* @param index index of the device which will be returned
*
* @returns pointer on the "index" device
*/
USBDeviceConnected * getDevice(uint8_t index);
/*
* If there is a HID device connected, the host stores the length of the report descriptor.
* This avoid to the driver to re-ask the configuration descriptor to request the report descriptor
*
* @returns length of the report descriptor
*/
inline uint16_t getLengthReportDescr() {
return lenReportDescr;
};
/**
* register a driver into the host associated with a callback function called when the device is disconnected
*
* @param dev device
* @param intf interface number
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
*/
template<typename T>
inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) {
int index = findDevice(dev);
if ((index != -1) && (mptr != NULL) && (tptr != NULL)) {
USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
deviceAttachedDriver[index][intf] = true;
dev->onDisconnect(intf, tptr, mptr);
}
}
/**
* register a driver into the host associated with a callback function called when the device is disconnected
*
* @param dev device
* @param intf interface number
* @param fn callback called when the specified device has been disconnected
*/
inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, void (*fn)(void)) {
int index = findDevice(dev);
if ((index != -1) && (fn != NULL)) {
USB_DBG("register driver for dev: %p on intf: %d", dev, intf);
deviceAttachedDriver[index][intf] = true;
dev->onDisconnect(intf, fn);
}
}
/**
* Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces)
*/
class Lock
{
public:
Lock(USBHost* pHost);
~Lock();
private:
USBHost* m_pHost;
};
friend class USBHostHub;
protected:
/**
* Virtual method called when a transfer has been completed
*
* @param addr list of the TDs which have been completed
*/
virtual void transferCompleted(volatile uint32_t addr);
/**
* Virtual method called when a device has been connected
*
* @param hub hub number of the device
* @param port port number of the device
* @param lowSpeed 1 if low speed, 0 otherwise
* @param hub_parent reference on the parent hub
*/
virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL);
/**
* Virtuel method called when a device has been disconnected
*
* @param hub hub number of the device
* @param port port number of the device
* @param addr list of the TDs which have been completed to dequeue freed TDs
*/
virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr);
private:
// singleton class -> constructor is private
USBHost();
static USBHost * instHost;
uint16_t lenReportDescr;
// endpoints
void unqueueEndpoint(USBEndpoint * ep) ;
USBEndpoint endpoints[MAX_ENDPOINT];
USBEndpoint* volatile control;
USBEndpoint* volatile headControlEndpoint;
USBEndpoint* volatile headBulkEndpoint;
USBEndpoint* volatile headInterruptEndpoint;
USBEndpoint* volatile tailControlEndpoint;
USBEndpoint* volatile tailBulkEndpoint;
USBEndpoint* volatile tailInterruptEndpoint;
bool controlEndpointAllocated;
// devices connected
USBDeviceConnected devices[MAX_DEVICE_CONNECTED];
bool deviceInUse[MAX_DEVICE_CONNECTED];
bool deviceAttachedDriver[MAX_DEVICE_CONNECTED][MAX_INTF];
bool deviceReset[MAX_DEVICE_CONNECTED];
bool deviceInited[MAX_DEVICE_CONNECTED];
#if MAX_HUB_NB
USBHostHub hubs[MAX_HUB_NB];
bool hub_in_use[MAX_HUB_NB];
#endif
// to store a setup packet
uint8_t setupPacket[8];
typedef struct {
uint8_t event_id;
void * td_addr;
uint8_t hub;
uint8_t port;
uint8_t lowSpeed;
uint8_t td_state;
void * hub_parent;
} message_t;
Thread usbThread;
void usb_process();
static void usb_process_static(void const * arg);
Mail<message_t, 10> mail_usb_event;
Mutex usb_mutex;
Mutex td_mutex;
// buffer for conf descriptor
uint8_t data[415];
/**
* Add a transfer on the TD linked list associated to an ED
*
* @param ed the transfer is associated to this ed
* @param buf pointer on a buffer where will be read/write data to send or receive
* @param len transfer length
*
* @return status of the transfer
*/
USB_TYPE addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) ;
/**
* Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device
*
* @param dev pointer on a USBDeviceConnected object
* @param ep pointer on the USBEndpoint which will be added
*
* return true if successful
*/
bool addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep) ;
/**
* Create an USBEndpoint descriptor. Warning: the USBEndpoint is not linked.
*
* @param type USBEndpoint type (CONTROL_ENDPOINT, BULK_ENDPOINT, INTERRUPT_ENDPOINT)
* @param dir USBEndpoint direction (no meaning for CONTROL_ENDPOINT)
* @param size USBEndpoint max packet size
* @param addr USBEndpoint address
*
* @returns pointer on the USBEndpoint created
*/
USBEndpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ;
/**
* Request the device descriptor
*
* @param dev request the device descriptor on this device
* @param buf buffer to store the device descriptor
* @param max_len_buf maximum size of buf
* @param len_dev_descr pointer to store the length of the packet transferred
*/
USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr = NULL);
/**
* Request the configuration descriptor
*
* @param dev request the configuration descriptor on this device
* @param buf buffer to store the configuration descriptor
* @param max_len_buf maximum size of buf
* @param len_conf_descr pointer to store the length of the packet transferred
*/
USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr = NULL);
/**
* Set the address of a specific device
*
* @param dev device to set the address
* @param address address
*/
USB_TYPE setAddress(USBDeviceConnected * dev, uint8_t address);
/**
* Set the configuration of a device
*
* @param dev device on which the specified configuration will be activated
* @param conf configuration number to activate (usually 1)
*/
USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf);
/**
* Free a specific device
*
* @param dev device to be freed
*/
void freeDevice(USBDeviceConnected * dev);
USB_TYPE controlTransfer( USBDeviceConnected * dev,
uint8_t requestType,
uint8_t request,
uint32_t value,
uint32_t index,
uint8_t * buf,
uint32_t len,
bool write);
USB_TYPE generalTransfer( USBDeviceConnected * dev,
USBEndpoint * ep,
uint8_t * buf,
uint32_t len,
bool blocking,
ENDPOINT_TYPE type,
bool write) ;
void fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len) ;
void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ;
int findDevice(USBDeviceConnected * dev) ;
int findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent = NULL) ;
uint8_t numberDriverAttached(USBDeviceConnected * dev);
/////////////////////////
/// FOR DEBUG
/////////////////////////
void printList(ENDPOINT_TYPE type);
};
#endif

View file

@ -0,0 +1,91 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOST_CONF_H
#define USBHOST_CONF_H
/*
* Maximum number of devices that can be connected
* to the usb host
*/
#define MAX_DEVICE_CONNECTED 5
/*
* Maximum of Hub connected to the usb host
*/
#define MAX_HUB_NB 2
/*
* Maximum number of ports on a USB hub
*/
#define MAX_HUB_PORT 4
/*
* Enable USBHostMSD
*/
#define USBHOST_MSD 1
/*
* Enable USBHostKeyboard
*/
#define USBHOST_KEYBOARD 1
/*
* Enable USBHostMouse
*/
#define USBHOST_MOUSE 1
/*
* Enable USBHostSerial or USBHostMultiSerial (if set > 1)
*/
#define USBHOST_SERIAL 1
/*
* Enable USB3Gmodule
*/
#define USBHOST_3GMODULE 1
/*
* Enable USB MIDI
*/
#define USBHOST_MIDI 1
/*
* Maximum number of interfaces of a usb device
*/
#define MAX_INTF 4
/*
* Maximum number of endpoints on each interface
*/
#define MAX_ENDPOINT_PER_INTERFACE 3
/*
* Maximum number of endpoint descriptors that can be allocated
*/
#define MAX_ENDPOINT (MAX_DEVICE_CONNECTED * MAX_INTF * MAX_ENDPOINT_PER_INTERFACE)
/*
* Maximum number of transfer descriptors that can be allocated
*/
#define MAX_TD (MAX_ENDPOINT*2)
/*
* usb_thread stack size
*/
#define USB_THREAD_STACK (256*4 + MAX_HUB_NB*256*4)
#endif

View file

@ -0,0 +1,226 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USB_INC_H
#define USB_INC_H
#include "mbed.h"
#include "toolchain.h"
enum USB_TYPE {
USB_TYPE_OK = 0,
// completion code
USB_TYPE_CRC_ERROR = 1,
USB_TYPE_BIT_STUFFING_ERROR = 2,
USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR = 3,
USB_TYPE_STALL_ERROR = 4,
USB_TYPE_DEVICE_NOT_RESPONDING_ERROR = 5,
USB_TYPE_PID_CHECK_FAILURE_ERROR = 6,
USB_TYPE_UNEXPECTED_PID_ERROR = 7,
USB_TYPE_DATA_OVERRUN_ERROR = 8,
USB_TYPE_DATA_UNDERRUN_ERROR = 9,
USB_TYPE_RESERVED = 9,
USB_TYPE_RESERVED_ = 10,
USB_TYPE_BUFFER_OVERRUN_ERROR = 12,
USB_TYPE_BUFFER_UNDERRUN_ERROR = 13,
// general usb state
USB_TYPE_DISCONNECTED = 14,
USB_TYPE_FREE = 15,
USB_TYPE_IDLE = 16,
USB_TYPE_PROCESSING = 17,
USB_TYPE_ERROR = 18,
};
enum ENDPOINT_DIRECTION {
OUT = 1,
IN
};
enum ENDPOINT_TYPE {
CONTROL_ENDPOINT = 0,
ISOCHRONOUS_ENDPOINT,
BULK_ENDPOINT,
INTERRUPT_ENDPOINT
};
#define AUDIO_CLASS 0x01
#define CDC_CLASS 0x02
#define HID_CLASS 0x03
#define MSD_CLASS 0x08
#define HUB_CLASS 0x09
#define SERIAL_CLASS 0x0A
// ------------------ HcControl Register ---------------------
#define OR_CONTROL_PLE 0x00000004
#define OR_CONTROL_CLE 0x00000010
#define OR_CONTROL_BLE 0x00000020
#define OR_CONTROL_HCFS 0x000000C0
#define OR_CONTROL_HC_OPER 0x00000080
// ----------------- HcCommandStatus Register -----------------
#define OR_CMD_STATUS_HCR 0x00000001
#define OR_CMD_STATUS_CLF 0x00000002
#define OR_CMD_STATUS_BLF 0x00000004
// --------------- HcInterruptStatus Register -----------------
#define OR_INTR_STATUS_WDH 0x00000002
#define OR_INTR_STATUS_RHSC 0x00000040
#define OR_INTR_STATUS_UE 0x00000010
// --------------- HcInterruptEnable Register -----------------
#define OR_INTR_ENABLE_WDH 0x00000002
#define OR_INTR_ENABLE_RHSC 0x00000040
#define OR_INTR_ENABLE_MIE 0x80000000
// ---------------- HcRhDescriptorA Register ------------------
#define OR_RH_STATUS_LPSC 0x00010000
#define OR_RH_STATUS_DRWE 0x00008000
// -------------- HcRhPortStatus[1:NDP] Register --------------
#define OR_RH_PORT_CCS 0x00000001
#define OR_RH_PORT_PRS 0x00000010
#define OR_RH_PORT_CSC 0x00010000
#define OR_RH_PORT_PRSC 0x00100000
#define OR_RH_PORT_LSDA 0x00000200
#define FI 0x2EDF // 12000 bits per frame (-1)
#define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI)
#define ED_SKIP (uint32_t) (0x00001000) // Skip this ep in queue
#define TD_ROUNDING (uint32_t) (0x00040000) // Buffer Rounding
#define TD_SETUP (uint32_t)(0) // Direction of Setup Packet
#define TD_IN (uint32_t)(0x00100000) // Direction In
#define TD_OUT (uint32_t)(0x00080000) // Direction Out
#define TD_DELAY_INT(x) (uint32_t)((x) << 21) // Delay Interrupt
#define TD_TOGGLE_0 (uint32_t)(0x02000000) // Toggle 0
#define TD_TOGGLE_1 (uint32_t)(0x03000000) // Toggle 1
#define TD_CC (uint32_t)(0xF0000000) // Completion Code
#define DEVICE_DESCRIPTOR (1)
#define CONFIGURATION_DESCRIPTOR (2)
#define INTERFACE_DESCRIPTOR (4)
#define ENDPOINT_DESCRIPTOR (5)
#define HID_DESCRIPTOR (33)
// ----------- Control RequestType Fields -----------
#define USB_DEVICE_TO_HOST 0x80
#define USB_HOST_TO_DEVICE 0x00
#define USB_REQUEST_TYPE_CLASS 0x20
#define USB_REQUEST_TYPE_STANDARD 0x00
#define USB_RECIPIENT_DEVICE 0x00
#define USB_RECIPIENT_INTERFACE 0x01
#define USB_RECIPIENT_ENDPOINT 0x02
// -------------- USB Standard Requests --------------
#define SET_ADDRESS 0x05
#define GET_DESCRIPTOR 0x06
#define SET_CONFIGURATION 0x09
#define SET_INTERFACE 0x0b
#define CLEAR_FEATURE 0x01
// -------------- USB Descriptor Length --------------
#define DEVICE_DESCRIPTOR_LENGTH 0x12
#define CONFIGURATION_DESCRIPTOR_LENGTH 0x09
// ------------ HostController Transfer Descriptor ------------
typedef struct HCTD {
__IO uint32_t control; // Transfer descriptor control
__IO uint8_t * currBufPtr; // Physical address of current buffer pointer
__IO HCTD * nextTD; // Physical pointer to next Transfer Descriptor
__IO uint8_t * bufEnd; // Physical address of end of buffer
void * ep; // ep address where a td is linked in
uint32_t dummy[3]; // padding
} PACKED HCTD;
// ----------- HostController EndPoint Descriptor -------------
typedef struct hcEd {
__IO uint32_t control; // Endpoint descriptor control
__IO HCTD * tailTD; // Physical address of tail in Transfer descriptor list
__IO HCTD * headTD; // Physcial address of head in Transfer descriptor list
__IO hcEd * nextED; // Physical address of next Endpoint descriptor
} PACKED HCED;
// ----------- Host Controller Communication Area ------------
typedef struct hcca {
__IO uint32_t IntTable[32]; // Interrupt Table
__IO uint32_t FrameNumber; // Frame Number
__IO uint32_t DoneHead; // Done Head
volatile uint8_t Reserved[116]; // Reserved for future use
volatile uint8_t Unknown[4]; // Unused
} PACKED HCCA;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} PACKED DeviceDescriptor;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} PACKED ConfigurationDescriptor;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} InterfaceDescriptor;
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} EndpointDescriptor;
typedef struct {
uint8_t bDescLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
uint16_t wHubCharacteristics;
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
uint8_t DeviceRemovable;
uint8_t PortPweCtrlMak;
} HubDescriptor;
#endif

View file

@ -0,0 +1,66 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USB_DEBUG_H
#define USB_DEBUG_H
//Debug is disabled by default
#define DEBUG 3 /*INFO,ERR,WARN*/
#define DEBUG_TRANSFER 0
#define DEBUG_EP_STATE 0
#define DEBUG_EVENT 0
#if (DEBUG > 3)
#define USB_DBG(x, ...) std::printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#else
#define USB_DBG(x, ...)
#endif
#if (DEBUG > 2)
#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#else
#define USB_INFO(x, ...)
#endif
#if (DEBUG > 1)
#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#else
#define USB_WARN(x, ...)
#endif
#if (DEBUG > 0)
#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#else
#define USB_ERR(x, ...)
#endif
#if (DEBUG_TRANSFER)
#define USB_DBG_TRANSFER(x, ...) std::printf("[USB_TRANSFER: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#else
#define USB_DBG_TRANSFER(x, ...)
#endif
#if (DEBUG_EVENT)
#define USB_DBG_EVENT(x, ...) std::printf("[USB_EVENT: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#else
#define USB_DBG_EVENT(x, ...)
#endif
#endif

View file

@ -0,0 +1,95 @@
/* IUSBHostSerial.h */
/* Copyright (c) 2010-2012 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.
*/
#ifndef IUSBHOSTSERIAL_H_
#define IUSBHOSTSERIAL_H_
/**
* Generic interface to abstract 3G dongles' impl
*/
#include "USBHostConf.h"
#ifdef USBHOST_3GMODULE
#include "IUSBHostSerialListener.h"
// This is needed by some versions of GCC
#undef putc
#undef getc
class IUSBHostSerial {
public:
enum IrqType {
RxIrq,
TxIrq
};
/*
* Get a char from the dongle's serial interface
*/
virtual int getc() = 0;
/*
* Put a char to the dongle's serial interface
*/
virtual int putc(int c) = 0;
/*
* Read a packet from the dongle's serial interface, to be called after multiple getc() calls
*/
virtual int readPacket() = 0;
/*
* Write a packet to the dongle's serial interface, to be called after multiple putc() calls
*/
virtual int writePacket() = 0;
/**
* Check the number of bytes available.
*
* @returns the number of bytes available
*/
virtual int readable() = 0;
/**
* Check the free space in output.
*
* @returns the number of bytes available
*/
virtual int writeable() = 0;
/**
* Attach a handler to call when a packet is received / when a packet has been transmitted.
*
* @param pListener instance of the listener deriving from the IUSBHostSerialListener
*/
virtual void attach(IUSBHostSerialListener* pListener) = 0;
/**
* Enable or disable readable/writeable callbacks
*/
virtual void setupIrq(bool en, IrqType irq = RxIrq) = 0;
};
#endif /* USBHOST_3GMODULE */
#endif /* IUSBHOSTSERIAL_H_ */

View file

@ -0,0 +1,37 @@
/* IUSBHostSerialListener.h */
/* Copyright (c) 2010-2012 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.
*/
#ifndef IUSBHOSTSERIALLISTENER_H_
#define IUSBHOSTSERIALLISTENER_H_
#include "USBHostConf.h"
#ifdef USBHOST_3GMODULE
class IUSBHostSerialListener
{
public:
virtual void readable() = 0; //Called when new data is available
virtual void writeable() = 0; //Called when new space is available
};
#endif /* USBHOST_3GMODULE */
#endif /* IUSBHOSTSERIALLISTENER_H_ */

View file

@ -0,0 +1,235 @@
/* Copyright (c) 2010-2012 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.
*/
#include "USBHostConf.h"
#ifdef USBHOST_3GMODULE
#include "dbg.h"
#include <stdint.h>
#include "rtos.h"
#include "WANDongle.h"
#include "WANDongleInitializer.h"
WANDongle::WANDongle() : m_pInitializer(NULL), m_serialCount(0), m_totalInitializers(0)
{
host = USBHost::getHostInst();
init();
}
bool WANDongle::connected() {
return dev_connected;
}
bool WANDongle::tryConnect()
{
//FIXME should run on USB thread
USB_DBG("Trying to connect device");
if (dev_connected) {
USB_DBG("Device is already connected!");
return true;
}
m_pInitializer = NULL;
//Protect from concurrent access from USB thread
USBHost::Lock lock(host);
for (int i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
if ((dev = host->getDevice(i)) != NULL)
{
m_pInitializer = NULL; //Will be set in setVidPid callback
USB_DBG("Enumerate");
int ret = host->enumerate(dev, this);
if(ret)
{
return false;
}
USB_DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());
if(m_pInitializer) //If an initializer has been found
{
USB_DBG("m_pInitializer=%p", m_pInitializer);
USB_DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid());
USB_DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid());
if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid()))
{
USB_DBG("The dongle is in virtual serial mode");
host->registerDriver(dev, 0, this, &WANDongle::init);
m_serialCount = m_pInitializer->getSerialPortCount();
if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS )
{
m_serialCount = WANDONGLE_MAX_SERIAL_PORTS;
}
for(int j = 0; j < m_serialCount; j++)
{
USB_DBG("Connecting serial port #%d", j+1);
USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, false));
USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
}
USB_DBG("Device connected");
dev_connected = true;
return true;
}
else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid()))
{
USB_DBG("Vodafone K3370 dongle detected in MSD mode");
//Try to switch
if( m_pInitializer->switchMode(dev) )
{
USB_DBG("Switched OK");
return false; //Will be connected on a next iteration
}
else
{
USB_ERR("Could not switch mode");
return false;
}
}
} //if()
} //if()
} //for()
return false;
}
bool WANDongle::disconnect()
{
dev_connected = false;
for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
{
m_serial[i].disconnect();
}
return true;
}
int WANDongle::getDongleType()
{
if( m_pInitializer != NULL )
{
return m_pInitializer->getType();
}
else
{
return WAN_DONGLE_TYPE_UNKNOWN;
}
}
IUSBHostSerial& WANDongle::getSerial(int index)
{
return m_serial[index];
}
int WANDongle::getSerialCount()
{
return m_serialCount;
}
//Private methods
void WANDongle::init()
{
m_pInitializer = NULL;
dev_connected = false;
for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++)
{
m_serial[i].init(host);
}
}
/*virtual*/ void WANDongle::setVidPid(uint16_t vid, uint16_t pid)
{
WANDongleInitializer* initializer;
for(int i = 0; i < m_totalInitializers; i++)
{
initializer = m_Initializers[i];
USB_DBG("initializer=%p", initializer);
USB_DBG("initializer->getSerialVid()=%04x", initializer->getSerialVid());
USB_DBG("initializer->getSerialPid()=%04x", initializer->getSerialPid());
if ((dev->getVid() == initializer->getSerialVid()) && (dev->getPid() == initializer->getSerialPid()))
{
USB_DBG("The dongle is in virtual serial mode");
m_pInitializer = initializer;
break;
}
else if ((dev->getVid() == initializer->getMSDVid()) && (dev->getPid() == initializer->getMSDPid()))
{
USB_DBG("Dongle detected in MSD mode");
m_pInitializer = initializer;
break;
}
initializer++;
} //for
if(m_pInitializer)
{
m_pInitializer->setVidPid(vid, pid);
}
}
/*virtual*/ bool WANDongle::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if(m_pInitializer)
{
return m_pInitializer->parseInterface(intf_nb, intf_class, intf_subclass, intf_protocol);
}
else
{
return false;
}
}
/*virtual*/ bool WANDongle::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if(m_pInitializer)
{
return m_pInitializer->useEndpoint(intf_nb, type, dir);
}
else
{
return false;
}
}
bool WANDongle::addInitializer(WANDongleInitializer* pInitializer)
{
if (m_totalInitializers >= WANDONGLE_MAX_INITIALIZERS)
return false;
m_Initializers[m_totalInitializers++] = pInitializer;
return true;
}
WANDongle::~WANDongle()
{
for(int i = 0; i < m_totalInitializers; i++)
delete m_Initializers[i];
}
#endif /* USBHOST_3GMODULE */

View file

@ -0,0 +1,108 @@
/* Copyright (c) 2010-2012 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.
*/
#ifndef WANDONGLE_H
#define WANDONGLE_H
#include "USBHostConf.h"
#ifdef USBHOST_3GMODULE
#include "USBHost.h"
#include "IUSBHostSerial.h"
#include "rtos.h"
#include "WANDongleSerialPort.h"
#include "WANDongleInitializer.h"
#include "IUSBEnumerator.h"
#define WANDONGLE_MAX_OUTEP_SIZE 64
#define WANDONGLE_MAX_INEP_SIZE 64
/** A class to use a WAN (3G/LTE) access dongle
*
*/
class WANDongle : public IUSBEnumerator {
public:
/*
* Constructor
*
* @param rootdir mount name
*/
WANDongle();
/*
* Destructor
*/
virtual ~WANDongle();
/*
* Check if a serial port device is connected
*
* @return true if a serial device is connected
*/
bool connected();
/*
* Try to connect device
*
* * @return true if connection was successful
*/
bool tryConnect();
/*
* Disconnect device
*
* * @return true if disconnection was successful
*/
bool disconnect();
int getDongleType();
IUSBHostSerial& getSerial(int index);
int getSerialCount();
bool addInitializer(WANDongleInitializer* pInitializer);
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
protected:
USBHost * host;
USBDeviceConnected * dev;
bool dev_connected;
WANDongleInitializer* m_pInitializer;
void init();
WANDongleSerialPort m_serial[WANDONGLE_MAX_SERIAL_PORTS];
int m_serialCount;
int m_totalInitializers;
WANDongleInitializer* m_Initializers[WANDONGLE_MAX_INITIALIZERS];
};
#endif /* USBHOST_3GMODULE */
#endif

View file

@ -0,0 +1,73 @@
/* Copyright (c) 2010-2012 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.
*/
#ifndef WANDONGLEINITIALIZER_H
#define WANDONGLEINITIALIZER_H
#include "USBHostConf.h"
#ifdef USBHOST_3GMODULE
#include <stdint.h>
#include "USBHost.h"
#include "IUSBEnumerator.h"
// [TODO] move these declarations to a proper place
#define WANDONGLE_MAX_SERIAL_PORTS 2
#define WANDONGLE_MAX_INITIALIZERS 6
#define WAN_DONGLE_TYPE_UNKNOWN (-1)
class WANDongleInitializer : public IUSBEnumerator
{
protected:
WANDongleInitializer(USBHost* pHost) { m_pHost = pHost; }
USBHost* m_pHost;
uint8_t m_serialIntfMap[WANDONGLE_MAX_SERIAL_PORTS];
public:
virtual ~WANDongleInitializer() {}
virtual uint16_t getMSDVid() = 0;
virtual uint16_t getMSDPid() = 0;
virtual uint16_t getSerialVid() = 0;
virtual uint16_t getSerialPid() = 0;
virtual bool switchMode(USBDeviceConnected* pDev) = 0;
virtual USBEndpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) {
return pDev->getEndpoint(m_serialIntfMap[serialPortNumber], BULK_ENDPOINT, tx ? OUT : IN, 0);
}
virtual int getSerialPortCount() = 0;
virtual void setVidPid(uint16_t vid, uint16_t pid) = 0;
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used
virtual int getType() = 0;
virtual uint8_t getSerialIntf(int index) { return m_serialIntfMap[index]; }
};
#endif /* USBHOST_3GMODULE */
#endif

View file

@ -0,0 +1,340 @@
/* Copyright (c) 2010-2012 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.
*/
#include "USBHostConf.h"
#ifdef USBHOST_3GMODULE
#define __DEBUG__ 0
#ifndef __MODULE__
#define __MODULE__ "WANDongleSerialPort.cpp"
#endif
#include "dbg.h"
#include <stdint.h>
#include "rtos.h"
#include "WANDongleSerialPort.h"
WANDongleSerialPort::WANDongleSerialPort() : cb_tx_en(false), cb_rx_en(false), listener(NULL)
{
reset();
}
void WANDongleSerialPort::init(USBHost* pHost)
{
host = pHost;
}
void WANDongleSerialPort::reset()
{
tx_mtx.lock();
rx_mtx.lock();
bulk_in = NULL;
bulk_out = NULL;
buf_out_len = 0;
max_out_size = 0;
lock_tx = false;
cb_tx_pending = false;
buf_in_len = 0;
buf_in_read_pos = 0;
lock_rx = false;
cb_rx_pending = false;
tx_mtx.unlock();
rx_mtx.unlock();
}
int WANDongleSerialPort::readPacket()
{
USB_DBG("Read packet on %p", this);
rx_mtx.lock();
if(lock_rx)
{
USB_ERR("Fail");
rx_mtx.unlock();
return -1;
}
if( bulk_in == NULL )
{
USB_WARN("Port is disconnected");
rx_mtx.unlock();
return -1;
}
lock_rx = true; //Receiving
rx_mtx.unlock();
// USB_DBG("readPacket");
//lock_rx.lock();
USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer
if(res != USB_TYPE_PROCESSING)
{
//lock_rx.unlock();
USB_ERR("host->bulkRead() returned %d", res);
Thread::wait(100);
return -1;
}
return 0;
}
int WANDongleSerialPort::writePacket()
{
tx_mtx.lock();
if(lock_tx)
{
USB_ERR("Fail");
tx_mtx.unlock();
return -1;
}
if( bulk_out == NULL )
{
USB_WARN("Port is disconnected");
tx_mtx.unlock();
return -1;
}
lock_tx = true; //Transmitting
tx_mtx.unlock();
// USB_DBG("writePacket");
//lock_tx.lock();
USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer
if(res != USB_TYPE_PROCESSING)
{
//lock_tx.unlock();
USB_ERR("host->bulkWrite() returned %d", res);
Thread::wait(100);
return -1;
}
return 0;
}
int WANDongleSerialPort::putc(int c)
{
tx_mtx.lock();
if(!lock_tx)
{
if(buf_out_len < max_out_size)
{
buf_out[buf_out_len] = (uint8_t)c;
buf_out_len++;
}
}
else
{
USB_ERR("CAN'T WRITE!");
}
tx_mtx.unlock();
return c;
}
int WANDongleSerialPort::getc()
{
rx_mtx.lock();
int c = 0;
if(!lock_rx)
{
if(buf_in_read_pos < buf_in_len)
{
c = (int)buf_in[buf_in_read_pos];
buf_in_read_pos++;
}
}
else
{
USB_ERR("CAN'T READ!");
}
rx_mtx.unlock();
return c;
}
int WANDongleSerialPort::readable()
{
rx_mtx.lock();
if (lock_rx)
{
rx_mtx.unlock();
return 0;
}
/* if( !lock_rx.trylock() )
{
return 0;
}*/
int res = buf_in_len - buf_in_read_pos;
//lock_rx.unlock();
rx_mtx.unlock();
return res;
}
int WANDongleSerialPort::writeable()
{
tx_mtx.lock();
if (lock_tx)
{
tx_mtx.unlock();
return 0;
}
/*if( !lock_tx.trylock() )
{
return 0;
}*/
int res = max_out_size - buf_out_len;
tx_mtx.unlock();
//lock_tx.unlock();
return res;
}
void WANDongleSerialPort::attach(IUSBHostSerialListener* pListener)
{
if(pListener == NULL)
{
setupIrq(false, RxIrq);
setupIrq(false, TxIrq);
}
listener = pListener;
if(pListener != NULL)
{
setupIrq(true, RxIrq);
setupIrq(true, TxIrq);
}
}
void WANDongleSerialPort::setupIrq(bool en, IrqType irq /*= RxIrq*/)
{
switch(irq)
{
case RxIrq:
rx_mtx.lock();
cb_rx_en = en;
if(en && cb_rx_pending)
{
cb_rx_pending = false;
rx_mtx.unlock();
listener->readable(); //Process the interrupt that was raised
}
else
{
rx_mtx.unlock();
}
break;
case TxIrq:
tx_mtx.lock();
cb_tx_en = en;
if(en && cb_tx_pending)
{
cb_tx_pending = false;
tx_mtx.unlock();
listener->writeable(); //Process the interrupt that was raised
}
else
{
tx_mtx.unlock();
}
break;
}
}
void WANDongleSerialPort::connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp )
{
dev = pDev;
bulk_in = pInEp;
bulk_out = pOutEp;
max_out_size = bulk_out->getSize();
if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE )
{
max_out_size = WANDONGLE_MAX_OUTEP_SIZE;
}
bulk_in->attach(this, &WANDongleSerialPort::rxHandler);
bulk_out->attach(this, &WANDongleSerialPort::txHandler);
readPacket(); //Start receiving data
}
void WANDongleSerialPort::disconnect( )
{
reset();
}
//Private methods
void WANDongleSerialPort::rxHandler()
{
if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success
{
buf_in_read_pos = 0;
buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length
//lock_rx.unlock();
rx_mtx.lock();
lock_rx = false; //Transmission complete
if(cb_rx_en)
{
rx_mtx.unlock();
listener->readable(); //Call handler from the IRQ context
//readPacket() should be called by the handler subsequently once the buffer has been emptied
}
else
{
cb_rx_pending = true; //Queue the callback
rx_mtx.unlock();
}
}
else //Error, try reading again
{
//lock_rx.unlock();
USB_DBG("Trying again");
readPacket();
}
}
void WANDongleSerialPort::txHandler()
{
if (((USBEndpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success
{
tx_mtx.lock();
buf_out_len = 0; //Reset length
lock_tx = false; //Transmission complete
//lock_tx.unlock();
if(cb_tx_en)
{
tx_mtx.unlock();
listener->writeable(); //Call handler from the IRQ context
//writePacket() should be called by the handler subsequently once the buffer has been filled
}
else
{
cb_tx_pending = true; //Queue the callback
tx_mtx.unlock();
}
}
else //Error, try reading again
{
//lock_tx.unlock();
writePacket();
}
}
#endif /* USBHOST_3GMODULE */

View file

@ -0,0 +1,133 @@
/* Copyright (c) 2010-2012 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.
*/
#ifndef WANDONGLESERIALPORT_H
#define WANDONGLESERIALPORT_H
#include "USBHostConf.h"
#ifdef USBHOST_3GMODULE
#include "USBHost.h"
#include "IUSBHostSerial.h"
#include "rtos.h"
#define WANDONGLE_MAX_OUTEP_SIZE 64
#define WANDONGLE_MAX_INEP_SIZE 64
/** A class to use a WAN (3G/LTE) access dongle
*
*/
class WANDongleSerialPort : public IUSBHostSerial {
public:
/*
* Constructor
*
*/
WANDongleSerialPort();
void init( USBHost* pHost );
void connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp );
void disconnect( );
/*
* Get a char from the dongle's serial interface
*/
virtual int getc();
/*
* Put a char to the dongle's serial interface
*/
virtual int putc(int c);
/*
* Read a packet from the dongle's serial interface, to be called after multiple getc() calls
*/
virtual int readPacket();
/*
* Write a packet to the dongle's serial interface, to be called after multiple putc() calls
*/
virtual int writePacket();
/**
* Check the number of bytes available.
*
* @returns the number of bytes available
*/
virtual int readable();
/**
* Check the free space in output.
*
* @returns the number of bytes available
*/
virtual int writeable();
/**
* Attach a handler to call when a packet is received / when a packet has been transmitted.
*
* @param pListener instance of the listener deriving from the IUSBHostSerialListener
*/
virtual void attach(IUSBHostSerialListener* pListener);
/**
* Enable or disable readable/writeable callbacks
*/
virtual void setupIrq(bool en, IrqType irq = RxIrq);
protected:
USBEndpoint * bulk_in;
USBEndpoint * bulk_out;
USBHost * host;
USBDeviceConnected * dev;
uint8_t buf_out[WANDONGLE_MAX_OUTEP_SIZE];
volatile uint32_t buf_out_len;
uint32_t max_out_size;
volatile bool lock_tx;
volatile bool cb_tx_en;
volatile bool cb_tx_pending;
Mutex tx_mtx;
uint8_t buf_in[WANDONGLE_MAX_INEP_SIZE];
volatile uint32_t buf_in_len;
volatile uint32_t buf_in_read_pos;
volatile bool lock_rx;
volatile bool cb_rx_en;
volatile bool cb_rx_pending;
Mutex rx_mtx;
IUSBHostSerialListener* listener;
void reset();
void rxHandler();
void txHandler();
};
#endif /* USBHOST_3GMODULE */
#endif

View file

@ -0,0 +1,184 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "USBHostKeyboard.h"
#if USBHOST_KEYBOARD
static uint8_t keymap[4][0x39] = {
{ 0, 0, 0, 0, 'a', 'b' /*0x05*/,
'c', 'd', 'e', 'f', 'g' /*0x0a*/,
'h', 'i', 'j', 'k', 'l'/*0x0f*/,
'm', 'n', 'o', 'p', 'q'/*0x14*/,
'r', 's', 't', 'u', 'v'/*0x19*/,
'w', 'x', 'y', 'z', '1'/*0x1E*/,
'2', '3', '4', '5', '6'/*0x23*/,
'7', '8', '9', '0', 0x0A /*enter*/, /*0x28*/
0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/
'=', '[', ']', '\\', '#', /*0x32*/
';', '\'', 0, ',', '.', /*0x37*/
'/'},
/* CTRL MODIFIER */
{ 0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/,
0, 0, 0, 0, 0/*0x19*/,
0, 0, 0, 0, 0/*0x1E*/,
0, 0, 0, 0, 0/*0x23*/,
0, 0, 0, 0, 0 /*enter*/, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/
0},
/* SHIFT MODIFIER */
{ 0, 0, 0, 0, 'A', 'B' /*0x05*/,
'C', 'D', 'E', 'F', 'G' /*0x0a*/,
'H', 'I', 'J', 'K', 'L'/*0x0f*/,
'M', 'N', 'O', 'P', 'Q'/*0x14*/,
'R', 'S', 'T', 'U', 'V'/*0x19*/,
'W', 'X', 'Y', 'Z', '!'/*0x1E*/,
'@', '#', '$', '%', '^'/*0x23*/,
'&', '*', '(', ')', 0, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
'+', '{', '}', '|', '~', /*0x32*/
':', '"', 0, '<', '>', /*0x37*/
'?'},
/* ALT MODIFIER */
{ 0, 0, 0, 0, 0, 0 /*0x05*/,
0, 0, 0, 0, 0 /*0x0a*/,
0, 0, 0, 0, 0/*0x0f*/,
0, 0, 0, 0, 0/*0x14*/,
0, 0, 0, 0, 0/*0x19*/,
0, 0, 0, 0, 0/*0x1E*/,
0, 0, 0, 0, 0/*0x23*/,
0, 0, 0, 0, 0 /*enter*/, /*0x28*/
0, 0, 0, 0, 0, /*0x2d*/
0, 0, 0, 0, 0, /*0x32*/
0, 0, 0, 0, 0, /*0x37*/
0}
};
USBHostKeyboard::USBHostKeyboard() {
host = USBHost::getHostInst();
init();
}
void USBHostKeyboard::init() {
dev = NULL;
int_in = NULL;
report_id = 0;
onKey = NULL;
onKeyCode = NULL;
dev_connected = false;
keyboard_intf = -1;
keyboard_device_found = false;
}
bool USBHostKeyboard::connected() {
return dev_connected;
}
bool USBHostKeyboard::connect() {
if (dev_connected) {
return true;
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
if (host->enumerate(dev, this))
break;
if (keyboard_device_found) {
int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in)
break;
USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
dev->setName("Keyboard", keyboard_intf);
host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
int_in->attach(this, &USBHostKeyboard::rxHandler);
host->interruptRead(dev, int_in, report, int_in->getSize(), false);
dev_connected = true;
return true;
}
}
}
init();
return false;
}
void USBHostKeyboard::rxHandler() {
int len = int_in->getLengthTransferred();
int index = (len == 9) ? 1 : 0;
int len_listen = int_in->getSize();
uint8_t key = 0;
if (len == 8 || len == 9) {
uint8_t modifier = (report[index] == 4) ? 3 : report[index];
len_listen = len;
key = keymap[modifier][report[index + 2]];
if (key && onKey) {
(*onKey)(key);
}
if ((report[index + 2] || modifier) && onKeyCode) {
(*onKeyCode)(report[index + 2], modifier);
}
}
if (dev && int_in)
host->interruptRead(dev, int_in, report, len_listen, false);
}
/*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for keyboard driver
}
/*virtual*/ bool USBHostKeyboard::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if ((keyboard_intf == -1) &&
(intf_class == HID_CLASS) &&
(intf_subclass == 0x01) &&
(intf_protocol == 0x01)) {
keyboard_intf = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostKeyboard::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (intf_nb == keyboard_intf) {
if (type == INTERRUPT_ENDPOINT && dir == IN) {
keyboard_device_found = true;
return true;
}
}
return false;
}
#endif

View file

@ -0,0 +1,102 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOSTKEYBOARD_H
#define USBHOSTKEYBOARD_H
#include "USBHostConf.h"
#if USBHOST_KEYBOARD
#include "USBHost.h"
/**
* A class to communicate a USB keyboard
*/
class USBHostKeyboard : public IUSBEnumerator {
public:
/**
* Constructor
*/
USBHostKeyboard();
/**
* Try to connect a keyboard device
*
* @return true if connection was successful
*/
bool connect();
/**
* Check if a keyboard is connected
*
* @returns true if a keyboard is connected
*/
bool connected();
/**
* Attach a callback called when a keyboard event is received
*
* @param ptr function pointer
*/
inline void attach(void (*ptr)(uint8_t key)) {
if (ptr != NULL) {
onKey = ptr;
}
}
/**
* Attach a callback called when a keyboard event is received
*
* @param ptr function pointer
*/
inline void attach(void (*ptr)(uint8_t keyCode, uint8_t modifier)) {
if (ptr != NULL) {
onKeyCode = ptr;
}
}
protected:
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
USBHost * host;
USBDeviceConnected * dev;
USBEndpoint * int_in;
uint8_t report[9];
int keyboard_intf;
bool keyboard_device_found;
bool dev_connected;
void rxHandler();
void (*onKey)(uint8_t key);
void (*onKeyCode)(uint8_t key, uint8_t modifier);
int report_id;
void init();
};
#endif
#endif

View file

@ -0,0 +1,153 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "USBHostMouse.h"
#if USBHOST_MOUSE
USBHostMouse::USBHostMouse() {
host = USBHost::getHostInst();
init();
}
void USBHostMouse::init() {
dev = NULL;
int_in = NULL;
onUpdate = NULL;
onButtonUpdate = NULL;
onXUpdate = NULL;
onYUpdate = NULL;
onZUpdate = NULL;
report_id = 0;
dev_connected = false;
mouse_device_found = false;
mouse_intf = -1;
buttons = 0;
x = 0;
y = 0;
z = 0;
}
bool USBHostMouse::connected() {
return dev_connected;
}
bool USBHostMouse::connect() {
int len_listen;
if (dev_connected) {
return true;
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
if(host->enumerate(dev, this))
break;
if (mouse_device_found) {
int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in)
break;
USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf);
dev->setName("Mouse", mouse_intf);
host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init);
int_in->attach(this, &USBHostMouse::rxHandler);
len_listen = int_in->getSize();
if (len_listen > sizeof(report)) {
len_listen = sizeof(report);
}
host->interruptRead(dev, int_in, report, len_listen, false);
dev_connected = true;
return true;
}
}
}
init();
return false;
}
void USBHostMouse::rxHandler() {
int len_listen = int_in->getSize();
if (onUpdate) {
(*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]);
}
if (onButtonUpdate && (buttons != (report[0] & 0x07))) {
(*onButtonUpdate)(report[0] & 0x07);
}
if (onXUpdate && (x != report[1])) {
(*onXUpdate)(report[1]);
}
if (onYUpdate && (y != report[2])) {
(*onYUpdate)(report[2]);
}
if (onZUpdate && (z != report[3])) {
(*onZUpdate)(report[3]);
}
// update mouse state
buttons = report[0] & 0x07;
x = report[1];
y = report[2];
z = report[3];
if (len_listen > sizeof(report)) {
len_listen = sizeof(report);
}
if (dev)
host->interruptRead(dev, int_in, report, len_listen, false);
}
/*virtual*/ void USBHostMouse::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for mouse driver
}
/*virtual*/ bool USBHostMouse::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if ((mouse_intf == -1) &&
(intf_class == HID_CLASS) &&
(intf_subclass == 0x01) &&
(intf_protocol == 0x02)) {
mouse_intf = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostMouse::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (intf_nb == mouse_intf) {
if (type == INTERRUPT_ENDPOINT && dir == IN) {
mouse_device_found = true;
return true;
}
}
return false;
}
#endif

View file

@ -0,0 +1,139 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOSTMOUSE_H
#define USBHOSTMOUSE_H
#include "USBHostConf.h"
#if USBHOST_MOUSE
#include "USBHost.h"
/**
* A class to communicate a USB mouse
*/
class USBHostMouse : public IUSBEnumerator {
public:
/**
* Constructor
*/
USBHostMouse();
/**
* Try to connect a mouse device
*
* @return true if connection was successful
*/
bool connect();
/**
* Check if a mouse is connected
*
* @returns true if a mouse is connected
*/
bool connected();
/**
* Attach a callback called when a mouse event is received
*
* @param ptr function pointer
*/
inline void attachEvent(void (*ptr)(uint8_t buttons, int8_t x, int8_t y, int8_t z)) {
if (ptr != NULL) {
onUpdate = ptr;
}
}
/**
* Attach a callback called when the button state changes
*
* @param ptr function pointer
*/
inline void attachButtonEvent(void (*ptr)(uint8_t buttons)) {
if (ptr != NULL) {
onButtonUpdate = ptr;
}
}
/**
* Attach a callback called when the X axis value changes
*
* @param ptr function pointer
*/
inline void attachXEvent(void (*ptr)(int8_t x)) {
if (ptr != NULL) {
onXUpdate = ptr;
}
}
/**
* Attach a callback called when the Y axis value changes
*
* @param ptr function pointer
*/
inline void attachYEvent(void (*ptr)(int8_t y)) {
if (ptr != NULL) {
onYUpdate = ptr;
}
}
/**
* Attach a callback called when the Z axis value changes (scrolling)
*
* @param ptr function pointer
*/
inline void attachZEvent(void (*ptr)(int8_t z)) {
if (ptr != NULL) {
onZUpdate = ptr;
}
}
protected:
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
USBHost * host;
USBDeviceConnected * dev;
USBEndpoint * int_in;
uint8_t report[4];
bool dev_connected;
bool mouse_device_found;
int mouse_intf;
uint8_t buttons;
int8_t x;
int8_t y;
int8_t z;
void rxHandler();
void (*onUpdate)(uint8_t buttons, int8_t x, int8_t y, int8_t z);
void (*onButtonUpdate)(uint8_t buttons);
void (*onXUpdate)(int8_t x);
void (*onYUpdate)(int8_t y);
void (*onZUpdate)(int8_t z);
int report_id;
void init();
};
#endif
#endif

View file

@ -0,0 +1,274 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "USBHostHub.h"
#if MAX_HUB_NB
#include "USBHost.h"
#include "dbg.h"
#define GET_STATUS 0x00
#define CLEAR_FEATURE 0x01
#define GET_STATE 0x02
#define SET_FEATURE 0x03
#define GET_DESCRIPTOR 0x06
#define PORT_CONNECTION_FEATURE (0x00)
#define PORT_ENABLE_FEATURE (0x01)
#define PORT_RESET_FEATURE (0x04)
#define PORT_POWER_FEATURE (0x08)
#define C_PORT_CONNECTION_FEATURE (16)
#define C_PORT_ENABLE_FEATURE (17)
#define C_PORT_RESET_FEATURE (20)
#define PORT_CONNECTION (1 << 0)
#define PORT_ENABLE (1 << 1)
#define PORT_SUSPEND (1 << 2)
#define PORT_OVER_CURRENT (1 << 3)
#define PORT_RESET (1 << 4)
#define PORT_POWER (1 << 8)
#define PORT_LOW_SPEED (1 << 9)
#define C_PORT_CONNECTION (1 << 16)
#define C_PORT_ENABLE (1 << 17)
#define C_PORT_SUSPEND (1 << 18)
#define C_PORT_OVER_CURRENT (1 << 19)
#define C_PORT_RESET (1 << 20)
USBHostHub::USBHostHub() {
host = NULL;
init();
}
void USBHostHub::init() {
dev_connected = false;
dev = NULL;
int_in = NULL;
dev_connected = false;
hub_intf = -1;
hub_device_found = false;
nb_port = 0;
hub_characteristics = 0;
for (int i = 0; i < MAX_HUB_PORT; i++) {
device_children[i] = NULL;
}
}
void USBHostHub::setHost(USBHost * host_) {
host = host_;
}
bool USBHostHub::connected()
{
return dev_connected;
}
bool USBHostHub::connect(USBDeviceConnected * dev)
{
if (dev_connected) {
return true;
}
if(host->enumerate(dev, this)) {
init();
return false;
}
if (hub_device_found) {
this->dev = dev;
int_in = dev->getEndpoint(hub_intf, INTERRUPT_ENDPOINT, IN);
if (!int_in) {
init();
return false;
}
USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, hub_intf);
dev->setName("Hub", hub_intf);
host->registerDriver(dev, hub_intf, this, &USBHostHub::disconnect);
int_in->attach(this, &USBHostHub::rxHandler);
// get HUB descriptor
host->controlRead( dev,
USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
GET_DESCRIPTOR,
0x29 << 8, 0, buf, sizeof(HubDescriptor));
nb_port = buf[2];
hub_characteristics = buf[3];
USB_DBG("Hub has %d port", nb_port);
for (uint8_t j = 1; j <= nb_port; j++) {
setPortFeature(PORT_POWER_FEATURE, j);
}
wait_ms(buf[5]*2);
host->interruptRead(dev, int_in, buf, 1, false);
dev_connected = true;
return true;
}
return false;
}
void USBHostHub::disconnect() {
init();
}
/*virtual*/ void USBHostHub::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for MSD driver
}
/*virtual*/ bool USBHostHub::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if ((hub_intf == -1) &&
(intf_class == HUB_CLASS) &&
(intf_subclass == 0) &&
(intf_protocol == 0)) {
hub_intf = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostHub::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (intf_nb == hub_intf) {
if ((type == INTERRUPT_ENDPOINT) && (dir == IN)) {
hub_device_found = true;
return true;
}
}
return false;
}
void USBHostHub::deviceConnected(USBDeviceConnected * dev) {
device_children[dev->getPort() - 1] = dev;
}
void USBHostHub::deviceDisconnected(USBDeviceConnected * dev) {
device_children[dev->getPort() - 1] = NULL;
}
void USBHostHub::hubDisconnected() {
for (uint8_t i = 0; i < MAX_HUB_PORT; i++) {
if (device_children[i] != NULL) {
host->freeDevice(device_children[i]);
}
}
}
void USBHostHub::rxHandler() {
uint32_t status;
if (int_in) {
if (int_in->getState() == USB_TYPE_IDLE) {
for (int port = 1; port <= nb_port; port++) {
status = getPortStatus(port);
USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status);
// if connection status has changed
if (status & C_PORT_CONNECTION) {
if (status & PORT_CONNECTION) {
USB_DBG("[hub handler hub: %d - port: %d] new device connected", dev->getHub(), port);
host->deviceConnected(dev->getHub() + 1, port, status & PORT_LOW_SPEED, this);
} else {
USB_DBG("[hub handler hub: %d - port: %d] device disconnected", dev->getHub(), port);
host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
}
clearPortFeature(C_PORT_CONNECTION_FEATURE, port);
}
if (status & C_PORT_RESET) {
clearPortFeature(C_PORT_RESET_FEATURE, port);
}
if (status & C_PORT_ENABLE) {
clearPortFeature(C_PORT_ENABLE_FEATURE, port);
}
if ((status & PORT_OVER_CURRENT)) {
USB_ERR("OVER CURRENT DETECTED\r\n");
clearPortFeature(PORT_OVER_CURRENT, port);
host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
}
}
}
host->interruptRead(dev, int_in, buf, 1, false);
}
}
void USBHostHub::portReset(uint8_t port) {
// reset port
uint32_t status;
USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this)
setPortFeature(PORT_RESET_FEATURE, port);
#if defined(TARGET_RZ_A1H)
Thread::wait(50); // Reset release waiting for Hi-Speed check.
#endif
while(1) {
status = getPortStatus(port);
if (status & (PORT_ENABLE | PORT_RESET))
break;
if (status & PORT_OVER_CURRENT) {
USB_ERR("OVER CURRENT DETECTED\r\n");
clearPortFeature(PORT_OVER_CURRENT, port);
host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
break;
}
Thread::wait(10);
}
}
void USBHostHub::setPortFeature(uint32_t feature, uint8_t port) {
host->controlWrite( dev,
USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
SET_FEATURE,
feature,
port,
NULL,
0);
}
void USBHostHub::clearPortFeature(uint32_t feature, uint8_t port) {
host->controlWrite( dev,
USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
CLEAR_FEATURE,
feature,
port,
NULL,
0);
}
uint32_t USBHostHub::getPortStatus(uint8_t port) {
uint32_t st;
host->controlRead( dev,
USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE | USB_RECIPIENT_ENDPOINT,
GET_STATUS,
0,
port,
(uint8_t *)&st,
4);
return st;
}
#endif

View file

@ -0,0 +1,125 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOSTHUB_H
#define USBHOSTHUB_H
#include "USBHostConf.h"
#if MAX_HUB_NB
#include "USBHostTypes.h"
#include "IUSBEnumerator.h"
class USBHost;
class USBDeviceConnected;
class USBEndpoint;
/**
* A class to use a USB Hub
*/
class USBHostHub : public IUSBEnumerator {
public:
/**
* Constructor
*/
USBHostHub();
/**
* Check if a USB Hub is connected
*
* @return true if a serial device is connected
*/
bool connected();
/**
* Try to connect device
*
* @param dev device to connect
* @return true if connection was successful
*/
bool connect(USBDeviceConnected * dev);
/**
* Automatically called by USBHost when a device
* has been enumerated by usb_thread
*
* @param dev device connected
*/
void deviceConnected(USBDeviceConnected * dev);
/**
* Automatically called by USBHost when a device
* has been disconnected from this hub
*
* @param dev device disconnected
*/
void deviceDisconnected(USBDeviceConnected * dev);
/**
* Rest a specific port
*
* @param port port number
*/
void portReset(uint8_t port);
/*
* Called by USBHost to set the instance of USBHost
*
* @param host host instance
*/
void setHost(USBHost * host);
/**
* Called by USBhost when a hub has been disconnected
*/
void hubDisconnected();
protected:
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
USBHost * host;
USBDeviceConnected * dev;
bool dev_connected;
USBEndpoint * int_in;
uint8_t nb_port;
uint8_t hub_characteristics;
void rxHandler();
uint8_t buf[sizeof(HubDescriptor)];
int hub_intf;
bool hub_device_found;
void setPortFeature(uint32_t feature, uint8_t port);
void clearPortFeature(uint32_t feature, uint8_t port);
uint32_t getPortStatus(uint8_t port);
USBDeviceConnected * device_children[MAX_HUB_PORT];
void init();
void disconnect();
};
#endif
#endif

View file

@ -0,0 +1,362 @@
/* Copyright (c) 2014 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.
*/
#include "USBHostMIDI.h"
#if USBHOST_MIDI
#include "dbg.h"
#define SET_LINE_CODING 0x20
USBHostMIDI::USBHostMIDI() {
host = USBHost::getHostInst();
size_bulk_in = 0;
size_bulk_out = 0;
init();
}
void USBHostMIDI::init() {
dev = NULL;
bulk_in = NULL;
bulk_out = NULL;
dev_connected = false;
midi_intf = -1;
midi_device_found = false;
sysExBufferPos = 0;
}
bool USBHostMIDI::connected() {
return dev_connected;
}
bool USBHostMIDI::connect() {
if (dev_connected) {
return true;
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
USB_DBG("Trying to connect MIDI device\r\n");
if (host->enumerate(dev, this)) {
break;
}
if (midi_device_found) {
bulk_in = dev->getEndpoint(midi_intf, BULK_ENDPOINT, IN);
bulk_out = dev->getEndpoint(midi_intf, BULK_ENDPOINT, OUT);
if (!bulk_in || !bulk_out) {
break;
}
USB_INFO("New MIDI device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, midi_intf);
dev->setName("MIDI", midi_intf);
host->registerDriver(dev, midi_intf, this, &USBHostMIDI::init);
size_bulk_in = bulk_in->getSize();
size_bulk_out = bulk_out->getSize();
bulk_in->attach(this, &USBHostMIDI::rxHandler);
host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
dev_connected = true;
return true;
}
}
}
init();
return false;
}
void USBHostMIDI::rxHandler() {
uint8_t *midi;
if (bulk_in) {
int length = bulk_in->getLengthTransferred();
if (bulk_in->getState() == USB_TYPE_IDLE || bulk_in->getState() == USB_TYPE_FREE) {
// MIDI event handling
for (int i = 0; i < length; i += 4) {
if (i + 4 > length) {
// length shortage, ignored.
break;
}
// read each four bytes
midi = &buf[i];
// process MIDI message
// switch by code index number
switch (midi[0] & 0xf) {
case 0: // miscellaneous function codes
miscellaneousFunctionCode(midi[1], midi[2], midi[3]);
break;
case 1: // cable events
cableEvent(midi[1], midi[2], midi[3]);
break;
case 2: // two bytes system common messages
systemCommonTwoBytes(midi[1], midi[2]);
break;
case 3: // three bytes system common messages
systemCommonThreeBytes(midi[1], midi[2], midi[3]);
break;
case 4: // SysEx starts or continues
sysExBuffer[sysExBufferPos++] = midi[1];
if (sysExBufferPos >= 64) {
systemExclusive(sysExBuffer, sysExBufferPos, true);
sysExBufferPos = 0;
}
sysExBuffer[sysExBufferPos++] = midi[2];
if (sysExBufferPos >= 64) {
systemExclusive(sysExBuffer, sysExBufferPos, true);
sysExBufferPos = 0;
}
sysExBuffer[sysExBufferPos++] = midi[3];
// SysEx continues. don't send
break;
case 5: // SysEx ends with single byte
sysExBuffer[sysExBufferPos++] = midi[1];
systemExclusive(sysExBuffer, sysExBufferPos, false);
sysExBufferPos = 0;
break;
case 6: // SysEx ends with two bytes
sysExBuffer[sysExBufferPos++] = midi[1];
if (sysExBufferPos >= 64) {
systemExclusive(sysExBuffer, sysExBufferPos, true);
sysExBufferPos = 0;
}
sysExBuffer[sysExBufferPos++] = midi[2];
systemExclusive(sysExBuffer, sysExBufferPos, false);
sysExBufferPos = 0;
break;
case 7: // SysEx ends with three bytes
sysExBuffer[sysExBufferPos++] = midi[1];
if (sysExBufferPos >= 64) {
systemExclusive(sysExBuffer, sysExBufferPos, true);
sysExBufferPos = 0;
}
sysExBuffer[sysExBufferPos++] = midi[2];
if (sysExBufferPos >= 64) {
systemExclusive(sysExBuffer, sysExBufferPos, true);
sysExBufferPos = 0;
}
sysExBuffer[sysExBufferPos++] = midi[3];
systemExclusive(sysExBuffer, sysExBufferPos, false);
sysExBufferPos = 0;
break;
case 8:
noteOff(midi[1] & 0xf, midi[2], midi[3]);
break;
case 9:
if (midi[3]) {
noteOn(midi[1] & 0xf, midi[2], midi[3]);
} else {
noteOff(midi[1] & 0xf, midi[2], midi[3]);
}
break;
case 10:
polyKeyPress(midi[1] & 0xf, midi[2], midi[3]);
break;
case 11:
controlChange(midi[1] & 0xf, midi[2], midi[3]);
break;
case 12:
programChange(midi[1] & 0xf, midi[2]);
break;
case 13:
channelPressure(midi[1] & 0xf, midi[2]);
break;
case 14:
pitchBend(midi[1] & 0xf, midi[2] | (midi[3] << 7));
break;
case 15:
singleByte(midi[1]);
break;
}
}
// read another message
host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
}
}
}
bool USBHostMIDI::sendMidiBuffer(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3) {
if (bulk_out) {
uint8_t midi[4];
midi[0] = data0;
midi[1] = data1;
midi[2] = data2;
midi[3] = data3;
if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
return true;
}
}
return false;
}
bool USBHostMIDI::sendMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3) {
return sendMidiBuffer(0, data1, data2, data3);
}
bool USBHostMIDI::sendCableEvent(uint8_t data1, uint8_t data2, uint8_t data3) {
return sendMidiBuffer(1, data1, data2, data3);
}
bool USBHostMIDI::sendSystemCommmonTwoBytes(uint8_t data1, uint8_t data2) {
return sendMidiBuffer(2, data1, data2, 0);
}
bool USBHostMIDI::sendSystemCommmonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3) {
return sendMidiBuffer(3, data1, data2, 0);
}
bool USBHostMIDI::sendSystemExclusive(uint8_t *buffer, int length) {
uint8_t midi[64];
int midiLength;
int midiPos;
if (bulk_out) {
for (int i = 0; i < length; i += 48) {
if (i + 48 >= length) {
// contains last data
midiLength = (((length - i) + 2) / 3) * 4;
for (int pos = i; pos < length; pos += 3) {
midiPos = (pos + 2) / 3 * 4;
if (pos + 3 >= length) {
// last data
switch (pos % 3) {
case 0:
midi[midiPos ] = 7;
midi[midiPos + 1] = buffer[pos ];
midi[midiPos + 2] = buffer[pos + 1];
midi[midiPos + 3] = buffer[pos + 2];
break;
case 1:
midi[midiPos ] = 5;
midi[midiPos + 1] = buffer[pos ];
midi[midiPos + 2] = 0;
midi[midiPos + 3] = 0;
break;
case 2:
midi[midiPos ] = 6;
midi[midiPos + 1] = buffer[pos ];
midi[midiPos + 2] = buffer[pos + 1];
midi[midiPos + 3] = 0;
break;
}
} else {
// has more data
midi[midiPos ] = 4;
midi[midiPos + 1] = buffer[pos ];
midi[midiPos + 2] = buffer[pos + 1];
midi[midiPos + 3] = buffer[pos + 2];
}
}
} else {
// has more data
midiLength = 64;
for (int pos = i; pos < length; pos += 3) {
midiPos = (pos + 2) / 3 * 4;
midi[midiPos ] = 4;
midi[midiPos + 1] = buffer[pos ];
midi[midiPos + 2] = buffer[pos + 1];
midi[midiPos + 3] = buffer[pos + 2];
}
}
if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, midiLength) != USB_TYPE_OK) {
return false;
}
}
return true;
}
return false;
}
bool USBHostMIDI::sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
return sendMidiBuffer(8, channel & 0xf | 0x80, note & 0x7f, velocity & 0x7f);
}
bool USBHostMIDI::sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
return sendMidiBuffer(9, channel & 0xf | 0x90, note & 0x7f, velocity & 0x7f);
}
bool USBHostMIDI::sendPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure) {
return sendMidiBuffer(10, channel & 0xf | 0xa0, note & 0x7f, pressure & 0x7f);
}
bool USBHostMIDI::sendControlChange(uint8_t channel, uint8_t key, uint8_t value) {
return sendMidiBuffer(11, channel & 0xf | 0xb0, key & 0x7f, value & 0x7f);
}
bool USBHostMIDI::sendProgramChange(uint8_t channel, uint8_t program) {
return sendMidiBuffer(12, channel & 0xf | 0xc0, program & 0x7f, 0);
}
bool USBHostMIDI::sendChannelPressure(uint8_t channel, uint8_t pressure) {
return sendMidiBuffer(13, channel & 0xf | 0xd0, pressure & 0x7f, 0);
}
bool USBHostMIDI::sendPitchBend(uint8_t channel, uint16_t value) {
return sendMidiBuffer(14, channel & 0xf | 0xe0, value & 0x7f, (value >> 7) & 0x7f);
}
bool USBHostMIDI::sendSingleByte(uint8_t data) {
return sendMidiBuffer(15, data, 0, 0);
}
/*virtual*/ void USBHostMIDI::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for this driver
}
/*virtual*/ bool USBHostMIDI::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
// USB MIDI class/subclass
if ((midi_intf == -1) &&
(intf_class == AUDIO_CLASS) &&
(intf_subclass == 0x03)) {
midi_intf = intf_nb;
return true;
}
// vendor specific device
if ((midi_intf == -1) &&
(intf_class == 0xff) &&
(intf_subclass == 0x03)) {
midi_intf = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostMIDI::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (intf_nb == midi_intf) {
if (type == BULK_ENDPOINT) {
midi_device_found = true;
return true;
}
}
return false;
}
#endif

View file

@ -0,0 +1,353 @@
/* Copyright (c) 2014 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.
*/
#ifndef USBHOSTMIDI_H
#define USBHOSTMIDI_H
#include "USBHostConf.h"
#if USBHOST_MIDI
#include "USBHost.h"
/**
* A class to communicate a USB MIDI device
*/
class USBHostMIDI : public IUSBEnumerator {
public:
/**
* Constructor
*/
USBHostMIDI();
/**
* Check if a USB MIDI device is connected
*
* @returns true if a midi device is connected
*/
bool connected();
/**
* Try to connect a midi device
*
* @return true if connection was successful
*/
bool connect();
/**
* Attach a callback called when miscellaneous function code is received
*
* @param ptr function pointer
* prototype: void onMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3);
*/
inline void attachMiscellaneousFunctionCode(void (*fn)(uint8_t, uint8_t, uint8_t)) {
miscellaneousFunctionCode = fn;
}
/**
* Attach a callback called when cable event is received
*
* @param ptr function pointer
* prototype: void onCableEvent(uint8_t data1, uint8_t data2, uint8_t data3);
*/
inline void attachCableEvent(void (*fn)(uint8_t, uint8_t, uint8_t)) {
cableEvent = fn;
}
/**
* Attach a callback called when system exclusive is received
*
* @param ptr function pointer
* prototype: void onSystemCommonTwoBytes(uint8_t data1, uint8_t data2);
*/
inline void attachSystemCommonTwoBytes(void (*fn)(uint8_t, uint8_t)) {
systemCommonTwoBytes = fn;
}
/**
* Attach a callback called when system exclusive is received
*
* @param ptr function pointer
* prototype: void onSystemCommonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3);
*/
inline void attachSystemCommonThreeBytes(void (*fn)(uint8_t, uint8_t, uint8_t)) {
systemCommonThreeBytes = fn;
}
/**
* Attach a callback called when system exclusive is received
*
* @param ptr function pointer
* prototype: void onSystemExclusive(uint8_t *data, uint16_t length, bool hasNextData);
*/
inline void attachSystemExclusive(void (*fn)(uint8_t *, uint16_t, bool)) {
systemExclusive = fn;
}
/**
* Attach a callback called when note on is received
*
* @param ptr function pointer
* prototype: void onNoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
*/
inline void attachNoteOn(void (*fn)(uint8_t, uint8_t, uint8_t)) {
noteOn = fn;
}
/**
* Attach a callback called when note off is received
*
* @param ptr function pointer
* prototype: void onNoteOff(uint8_t channel, uint8_t note, uint8_t velocity);
*/
inline void attachNoteOff(void (*fn)(uint8_t, uint8_t, uint8_t)) {
noteOff = fn;
}
/**
* Attach a callback called when poly keypress is received
*
* @param ptr function pointer
* prototype: void onPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure);
*/
inline void attachPolyKeyPress(void (*fn)(uint8_t, uint8_t, uint8_t)) {
polyKeyPress = fn;
}
/**
* Attach a callback called when control change is received
*
* @param ptr function pointer
* prototype: void onControlChange(uint8_t channel, uint8_t key, uint8_t value);
*/
inline void attachControlChange(void (*fn)(uint8_t, uint8_t, uint8_t)) {
controlChange = fn;
}
/**
* Attach a callback called when program change is received
*
* @param ptr function pointer
* prototype: void onProgramChange(uint8_t channel, uint8_t program);
*/
inline void attachProgramChange(void (*fn)(uint8_t, uint8_t)) {
programChange = fn;
}
/**
* Attach a callback called when channel pressure is received
*
* @param ptr function pointer
* prototype: void onChannelPressure(uint8_t channel, uint8_t pressure);
*/
inline void attachChannelPressure(void (*fn)(uint8_t, uint8_t)) {
channelPressure = fn;
}
/**
* Attach a callback called when pitch bend is received
*
* @param ptr function pointer
* prototype: void onPitchBend(uint8_t channel, uint16_t value);
*/
inline void attachPitchBend(void (*fn)(uint8_t, uint16_t)) {
pitchBend = fn;
}
/**
* Attach a callback called when single byte is received
*
* @param ptr function pointer
* prototype: void onSingleByte(uint8_t value);
*/
inline void attachSingleByte(void (*fn)(uint8_t)) {
singleByte = fn;
}
/**
* Send a cable event with 3 bytes event
*
* @param data1 0-255
* @param data2 0-255
* @param data3 0-255
* @return true if message sent successfully
*/
bool sendMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3);
/**
* Send a cable event with 3 bytes event
*
* @param data1 0-255
* @param data2 0-255
* @param data3 0-255
* @return true if message sent successfully
*/
bool sendCableEvent(uint8_t data1, uint8_t data2, uint8_t data3);
/**
* Send a system common message with 2 bytes event
*
* @param data1 0-255
* @param data2 0-255
* @return true if message sent successfully
*/
bool sendSystemCommmonTwoBytes(uint8_t data1, uint8_t data2);
/**
* Send a system common message with 3 bytes event
*
* @param data1 0-255
* @param data2 0-255
* @param data3 0-255
* @return true if message sent successfully
*/
bool sendSystemCommmonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3);
/**
* Send a system exclusive event
*
* @param buffer, starts with 0xF0, and end with 0xf7
* @param length
* @return true if message sent successfully
*/
bool sendSystemExclusive(uint8_t *buffer, int length);
/**
* Send a note off event
*
* @param channel 0-15
* @param note 0-127
* @param velocity 0-127
* @return true if message sent successfully
*/
bool sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity);
/**
* Send a note on event
*
* @param channel 0-15
* @param note 0-127
* @param velocity 0-127 (0 means note off)
* @return true if message sent successfully
*/
bool sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
/**
* Send a poly keypress event
*
* @param channel 0-15
* @param note 0-127
* @param pressure 0-127
* @return true if message sent successfully
*/
bool sendPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure);
/**
* Send a control change event
*
* @param channel 0-15
* @param key 0-127
* @param value 0-127
* @return true if message sent successfully
*/
bool sendControlChange(uint8_t channel, uint8_t key, uint8_t value);
/**
* Send a program change event
*
* @param channel 0-15
* @param program 0-127
* @return true if message sent successfully
*/
bool sendProgramChange(uint8_t channel, uint8_t program);
/**
* Send a channel pressure event
*
* @param channel 0-15
* @param pressure 0-127
* @return true if message sent successfully
*/
bool sendChannelPressure(uint8_t channel, uint8_t pressure);
/**
* Send a control change event
*
* @param channel 0-15
* @param key 0(lower)-8191(center)-16383(higher)
* @return true if message sent successfully
*/
bool sendPitchBend(uint8_t channel, uint16_t value);
/**
* Send a single byte event
*
* @param data 0-255
* @return true if message sent successfully
*/
bool sendSingleByte(uint8_t data);
protected:
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
USBHost * host;
USBDeviceConnected * dev;
USBEndpoint * bulk_in;
USBEndpoint * bulk_out;
uint32_t size_bulk_in;
uint32_t size_bulk_out;
bool dev_connected;
void init();
uint8_t buf[64];
void rxHandler();
uint16_t sysExBufferPos;
uint8_t sysExBuffer[64];
void (*miscellaneousFunctionCode)(uint8_t, uint8_t, uint8_t);
void (*cableEvent)(uint8_t, uint8_t, uint8_t);
void (*systemCommonTwoBytes)(uint8_t, uint8_t);
void (*systemCommonThreeBytes)(uint8_t, uint8_t, uint8_t);
void (*systemExclusive)(uint8_t *, uint16_t, bool);
void (*noteOff)(uint8_t, uint8_t, uint8_t);
void (*noteOn)(uint8_t, uint8_t, uint8_t);
void (*polyKeyPress)(uint8_t, uint8_t, uint8_t);
void (*controlChange)(uint8_t, uint8_t, uint8_t);
void (*programChange)(uint8_t, uint8_t);
void (*channelPressure)(uint8_t, uint8_t);
void (*pitchBend)(uint8_t, uint16_t);
void (*singleByte)(uint8_t);
bool sendMidiBuffer(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3);
int midi_intf;
bool midi_device_found;
};
#endif /* USBHOST_MIDI */
#endif /* USBHOSTMIDI_H */

View file

@ -0,0 +1,366 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "USBHostMSD.h"
#if USBHOST_MSD
#include "dbg.h"
#define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
#define DEVICE_TO_HOST 0x80
#define HOST_TO_DEVICE 0x00
#define GET_MAX_LUN (0xFE)
#define BO_MASS_STORAGE_RESET (0xFF)
USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir)
{
host = USBHost::getHostInst();
init();
}
void USBHostMSD::init() {
dev_connected = false;
dev = NULL;
bulk_in = NULL;
bulk_out = NULL;
dev_connected = false;
blockSize = 0;
blockCount = 0;
msd_intf = -1;
msd_device_found = false;
disk_init = false;
dev_connected = false;
nb_ep = 0;
}
bool USBHostMSD::connected()
{
return dev_connected;
}
bool USBHostMSD::connect()
{
if (dev_connected) {
return true;
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if ((dev = host->getDevice(i)) != NULL) {
USB_DBG("Trying to connect MSD device\r\n");
if(host->enumerate(dev, this))
break;
if (msd_device_found) {
bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN);
bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT);
if (!bulk_in || !bulk_out)
continue;
USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
dev->setName("MSD", msd_intf);
host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
dev_connected = true;
return true;
}
} //if()
} //for()
init();
return false;
}
/*virtual*/ void USBHostMSD::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for MSD driver
}
/*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if ((msd_intf == -1) &&
(intf_class == MSD_CLASS) &&
(intf_subclass == 0x06) &&
(intf_protocol == 0x50)) {
msd_intf = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostMSD::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (intf_nb == msd_intf) {
if (type == BULK_ENDPOINT) {
nb_ep++;
if (nb_ep == 2)
msd_device_found = true;
return true;
}
}
return false;
}
int USBHostMSD::testUnitReady() {
USB_DBG("Test unit ready");
return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0);
}
int USBHostMSD::readCapacity() {
USB_DBG("Read capacity");
uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0};
uint8_t result[8];
int status = SCSITransfer(cmd, 10, DEVICE_TO_HOST, result, 8);
if (status == 0) {
blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3];
blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7];
USB_INFO("MSD [dev: %p] - blockCount: %lld, blockSize: %d, Capacity: %lld\r\n", dev, blockCount, blockSize, blockCount*blockSize);
}
return status;
}
int USBHostMSD::SCSIRequestSense() {
USB_DBG("Request sense");
uint8_t cmd[6] = {0x03,0,0,0,18,0};
uint8_t result[18];
int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 18);
return status;
}
int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code) {
USB_DBG("Inquiry");
uint8_t evpd = (page_code == 0) ? 0 : 1;
uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0};
uint8_t result[36];
int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 36);
if (status == 0) {
char vid_pid[17];
memcpy(vid_pid, &result[8], 8);
vid_pid[8] = 0;
USB_INFO("MSD [dev: %p] - Vendor ID: %s", dev, vid_pid);
memcpy(vid_pid, &result[16], 16);
vid_pid[16] = 0;
USB_INFO("MSD [dev: %p] - Product ID: %s", dev, vid_pid);
memcpy(vid_pid, &result[32], 4);
vid_pid[4] = 0;
USB_INFO("MSD [dev: %p] - Product rev: %s", dev, vid_pid);
}
return status;
}
int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep) {
// if ep stalled: send clear feature
if (res == USB_TYPE_STALL_ERROR) {
res = host->controlWrite( dev,
USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
CLEAR_FEATURE,
0, ep->getAddress(), NULL, 0);
// set state to IDLE if clear feature successful
if (res == USB_TYPE_OK) {
ep->setState(USB_TYPE_IDLE);
}
}
if (res != USB_TYPE_OK)
return -1;
return 0;
}
int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) {
int res = 0;
cbw.Signature = CBW_SIGNATURE;
cbw.Tag = 0;
cbw.DataLength = transfer_len;
cbw.Flags = flags;
cbw.LUN = 0;
cbw.CBLength = cmd_len;
memset(cbw.CB,0,sizeof(cbw.CB));
if (cmd) {
memcpy(cbw.CB,cmd,cmd_len);
}
// send the cbw
USB_DBG("Send CBW");
res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31);
if (checkResult(res, bulk_out))
return -1;
// data stage if needed
if (data) {
USB_DBG("data stage");
if (flags == HOST_TO_DEVICE) {
res = host->bulkWrite(dev, bulk_out, data, transfer_len);
if (checkResult(res, bulk_out))
return -1;
} else if (flags == DEVICE_TO_HOST) {
res = host->bulkRead(dev, bulk_in, data, transfer_len);
if (checkResult(res, bulk_in))
return -1;
}
}
// status stage
csw.Signature = 0;
USB_DBG("Read CSW");
res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13);
if (checkResult(res, bulk_in))
return -1;
if (csw.Signature != CSW_SIGNATURE) {
return -1;
}
USB_DBG("recv csw: status: %d", csw.Status);
// ModeSense?
if ((csw.Status == 1) && (cmd[0] != 0x03)) {
USB_DBG("request mode sense");
return SCSIRequestSense();
}
// perform reset recovery
if ((csw.Status == 2) && (cmd[0] != 0x03)) {
// send Bulk-Only Mass Storage Reset request
res = host->controlWrite( dev,
USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
BO_MASS_STORAGE_RESET,
0, msd_intf, NULL, 0);
// unstall both endpoints
res = host->controlWrite( dev,
USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
CLEAR_FEATURE,
0, bulk_in->getAddress(), NULL, 0);
res = host->controlWrite( dev,
USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
CLEAR_FEATURE,
0, bulk_out->getAddress(), NULL, 0);
}
return csw.Status;
}
int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) {
uint8_t cmd[10];
memset(cmd,0,10);
cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
cmd[2] = (block >> 24) & 0xff;
cmd[3] = (block >> 16) & 0xff;
cmd[4] = (block >> 8) & 0xff;
cmd[5] = block & 0xff;
cmd[7] = (nbBlock >> 8) & 0xff;
cmd[8] = nbBlock & 0xff;
return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock);
}
int USBHostMSD::getMaxLun() {
uint8_t buf[1], res;
res = host->controlRead( dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
0xfe, 0, msd_intf, buf, 1);
USB_DBG("max lun: %d", buf[0]);
return res;
}
int USBHostMSD::disk_initialize() {
USB_DBG("FILESYSTEM: init");
uint16_t i, timeout = 10;
getMaxLun();
for (i = 0; i < timeout; i++) {
Thread::wait(100);
if (!testUnitReady())
break;
}
if (i == timeout) {
disk_init = false;
return -1;
}
inquiry(0, 0);
disk_init = 1;
return readCapacity();
}
int USBHostMSD::disk_write(const uint8_t* buffer, uint64_t block_number, uint8_t count) {
USB_DBG("FILESYSTEM: write block: %lld, count: %d", block_number, count);
if (!disk_init) {
disk_initialize();
}
if (!disk_init)
return -1;
for (uint64_t b = block_number; b < block_number + count; b++) {
if (dataTransfer((uint8_t*)buffer, b, 1, HOST_TO_DEVICE))
return -1;
buffer += 512;
}
return 0;
}
int USBHostMSD::disk_read(uint8_t* buffer, uint64_t block_number, uint8_t count) {
USB_DBG("FILESYSTEM: read block: %lld, count: %d", block_number, count);
if (!disk_init) {
disk_initialize();
}
if (!disk_init)
return -1;
for (uint64_t b = block_number; b < block_number + count; b++) {
if (dataTransfer((uint8_t*)buffer, b, 1, DEVICE_TO_HOST))
return -1;
buffer += 512;
}
return 0;
}
uint64_t USBHostMSD::disk_sectors() {
USB_DBG("FILESYSTEM: sectors");
if (!disk_init) {
disk_initialize();
}
if (!disk_init)
return 0;
return blockCount;
}
#endif

View file

@ -0,0 +1,119 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOSTMSD_H
#define USBHOSTMSD_H
#include "USBHostConf.h"
#if USBHOST_MSD
#include "USBHost.h"
#include "FATFileSystem.h"
/**
* A class to communicate a USB flash disk
*/
class USBHostMSD : public IUSBEnumerator, public FATFileSystem {
public:
/**
* Constructor
*
* @param rootdir mount name
*/
USBHostMSD(const char * rootdir);
/**
* Check if a MSD device is connected
*
* @return true if a MSD device is connected
*/
bool connected();
/**
* Try to connect to a MSD device
*
* @return true if connection was successful
*/
bool connect();
protected:
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
// From FATFileSystem
virtual int disk_initialize();
virtual int disk_status() {return 0;};
virtual int disk_read(uint8_t* buffer, uint64_t sector, uint8_t count);
virtual int disk_write(const uint8_t* buffer, uint64_t sector, uint8_t count);
virtual int disk_sync() {return 0;};
virtual uint64_t disk_sectors();
private:
USBHost * host;
USBDeviceConnected * dev;
bool dev_connected;
USBEndpoint * bulk_in;
USBEndpoint * bulk_out;
uint8_t nb_ep;
// Bulk-only CBW
typedef struct {
uint32_t Signature;
uint32_t Tag;
uint32_t DataLength;
uint8_t Flags;
uint8_t LUN;
uint8_t CBLength;
uint8_t CB[16];
} PACKED CBW;
// Bulk-only CSW
typedef struct {
uint32_t Signature;
uint32_t Tag;
uint32_t DataResidue;
uint8_t Status;
} PACKED CSW;
CBW cbw;
CSW csw;
int SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len);
int testUnitReady();
int readCapacity();
int inquiry(uint8_t lun, uint8_t page_code);
int SCSIRequestSense();
int dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction);
int checkResult(uint8_t res, USBEndpoint * ep);
int getMaxLun();
int blockSize;
uint64_t blockCount;
int msd_intf;
bool msd_device_found;
bool disk_init;
void init();
};
#endif
#endif

View file

@ -0,0 +1,89 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MTXCIRCBUFFER_H
#define MTXCIRCBUFFER_H
#include "stdint.h"
#include "rtos.h"
//Mutex protected circular buffer
template<typename T, int size>
class MtxCircBuffer {
public:
MtxCircBuffer() {
write = 0;
read = 0;
}
bool isFull() {
mtx.lock();
bool r = (((write + 1) % size) == read);
mtx.unlock();
return r;
}
bool isEmpty() {
mtx.lock();
bool r = (read == write);
mtx.unlock();
return r;
}
void flush() {
write = 0;
read = 0;
}
void queue(T k) {
mtx.lock();
while (((write + 1) % size) == read) {
mtx.unlock();
Thread::wait(10);
mtx.lock();
}
buf[write++] = k;
write %= size;
mtx.unlock();
}
uint16_t available() {
mtx.lock();
uint16_t a = (write >= read) ? (write - read) : (size - read + write);
mtx.unlock();
return a;
}
bool dequeue(T * c) {
mtx.lock();
bool empty = (read == write);
if (!empty) {
*c = buf[read++];
read %= size;
}
mtx.unlock();
return (!empty);
}
private:
volatile uint16_t write;
volatile uint16_t read;
volatile T buf[size];
Mutex mtx;
};
#endif

View file

@ -0,0 +1,345 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "USBHostSerial.h"
#if USBHOST_SERIAL
#include "dbg.h"
#define CHECK_INTERFACE(cls,subcls,proto) \
(((cls == 0xFF) && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */ || \
((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ )
#if (USBHOST_SERIAL <= 1)
USBHostSerial::USBHostSerial()
{
host = USBHost::getHostInst();
ports_found = 0;
dev_connected = false;
}
bool USBHostSerial::connected()
{
return dev_connected;
}
void USBHostSerial::disconnect(void)
{
ports_found = 0;
dev = NULL;
}
bool USBHostSerial::connect() {
if (dev)
{
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (dev == d)
return true;
}
disconnect();
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (d != NULL) {
USB_DBG("Trying to connect serial device \r\n");
if(host->enumerate(d, this))
break;
USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN);
USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT);
if (bulk_in && bulk_out)
{
USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out);
dev = d;
dev_connected = true;
}
}
}
return dev != NULL;
}
/*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for MSD driver
}
/*virtual*/ bool USBHostSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if (!ports_found &&
CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
port_intf = intf_nb;
ports_found = true;
return true;
}
return false;
}
/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (ports_found && (intf_nb == port_intf)) {
if (type == BULK_ENDPOINT)
return true;
}
return false;
}
#else // (USBHOST_SERIAL > 1)
//------------------------------------------------------------------------------
USBHostMultiSerial::USBHostMultiSerial()
{
host = USBHost::getHostInst();
dev = NULL;
memset(ports, NULL, sizeof(ports));
ports_found = 0;
dev_connected = false;
}
USBHostMultiSerial::~USBHostMultiSerial()
{
disconnect();
}
bool USBHostMultiSerial::connected()
{
return dev_connected;
}
void USBHostMultiSerial::disconnect(void)
{
for (int port = 0; port < USBHOST_SERIAL; port ++)
{
if (ports[port])
{
delete ports[port];
ports[port] = NULL;
}
}
ports_found = 0;
dev = NULL;
}
bool USBHostMultiSerial::connect() {
if (dev)
{
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (dev == d)
return true;
}
disconnect();
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (d != NULL) {
USB_DBG("Trying to connect serial device \r\n");
if(host->enumerate(d, this))
break;
for (int port = 0; port < ports_found; port ++)
{
USBEndpoint* bulk_in = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN);
USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT);
if (bulk_in && bulk_out)
{
ports[port] = new USBHostSerialPort();
if (ports[port])
{
ports[port]->connect(host,d,port_intf[port],bulk_in, bulk_out);
dev = d;
dev_connected = true;
}
}
}
}
}
return dev != NULL;
}
/*virtual*/ void USBHostMultiSerial::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for MSD driver
}
/*virtual*/ bool USBHostMultiSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if ((ports_found < USBHOST_SERIAL) &&
CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
port_intf[ports_found++] = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) {
if (type == BULK_ENDPOINT)
return true;
}
return false;
}
#endif
//------------------------------------------------------------------------------
#define SET_LINE_CODING 0x20
USBHostSerialPort::USBHostSerialPort(): circ_buf()
{
init();
}
void USBHostSerialPort::init(void)
{
host = NULL;
dev = NULL;
serial_intf = NULL;
size_bulk_in = 0;
size_bulk_out = 0;
bulk_in = NULL;
bulk_out = NULL;
line_coding.baudrate = 9600;
line_coding.data_bits = 8;
line_coding.parity = None;
line_coding.stop_bits = 1;
circ_buf.flush();
}
void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev,
uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out)
{
host = _host;
dev = _dev;
serial_intf = _serial_intf;
bulk_in = _bulk_in;
bulk_out = _bulk_out;
USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf);
dev->setName("Serial", serial_intf);
host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init);
baud(9600);
size_bulk_in = bulk_in->getSize();
size_bulk_out = bulk_out->getSize();
bulk_in->attach(this, &USBHostSerialPort::rxHandler);
bulk_out->attach(this, &USBHostSerialPort::txHandler);
host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
}
void USBHostSerialPort::rxHandler() {
if (bulk_in) {
int len = bulk_in->getLengthTransferred();
if (bulk_in->getState() == USB_TYPE_IDLE) {
for (int i = 0; i < len; i++) {
circ_buf.queue(buf[i]);
}
rx.call();
host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
}
}
}
void USBHostSerialPort::txHandler() {
if (bulk_out) {
if (bulk_out->getState() == USB_TYPE_IDLE) {
tx.call();
}
}
}
int USBHostSerialPort::_putc(int c) {
if (bulk_out) {
if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) {
return 1;
}
}
return -1;
}
void USBHostSerialPort::baud(int baudrate) {
line_coding.baudrate = baudrate;
format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits);
}
void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) {
line_coding.data_bits = bits;
line_coding.parity = parity;
line_coding.stop_bits = (stop_bits == 1) ? 0 : 2;
// set line coding
host->controlWrite( dev,
USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
SET_LINE_CODING,
0, serial_intf, (uint8_t *)&line_coding, 7);
}
int USBHostSerialPort::_getc() {
uint8_t c = 0;
if (bulk_in == NULL) {
init();
return -1;
}
while (circ_buf.isEmpty());
circ_buf.dequeue(&c);
return c;
}
int USBHostSerialPort::writeBuf(const char* b, int s)
{
int c = 0;
if (bulk_out)
{
while (c < s)
{
int i = (s < size_bulk_out) ? s : size_bulk_out;
if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK)
c += i;
}
}
return s;
}
int USBHostSerialPort::readBuf(char* b, int s)
{
int i = 0;
if (bulk_in)
{
for (i = 0; i < s; )
b[i++] = getc();
}
return i;
}
uint8_t USBHostSerialPort::available() {
return circ_buf.available();
}
#endif

View file

@ -0,0 +1,231 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOSTSERIAL_H
#define USBHOSTSERIAL_H
#include "USBHostConf.h"
#if USBHOST_SERIAL
#include "USBHost.h"
#include "Stream.h"
#include "MtxCircBuffer.h"
/**
* A class to communicate a USB virtual serial port
*/
class USBHostSerialPort : public Stream {
public:
/**
* Constructor
*/
USBHostSerialPort();
enum IrqType {
RxIrq,
TxIrq
};
enum Parity {
None = 0,
Odd,
Even,
Mark,
Space
};
void connect(USBHost* _host, USBDeviceConnected * _dev,
uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out);
/**
* Check the number of bytes available.
*
* @returns the number of bytes available
*/
uint8_t available();
/**
* Attach a member function to call when a packet is received.
*
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
* @param irq irq type
*/
template<typename T>
inline void attach(T* tptr, void (T::*mptr)(void), IrqType irq = RxIrq) {
if ((mptr != NULL) && (tptr != NULL)) {
if (irq == RxIrq) {
rx.attach(tptr, mptr);
} else {
tx.attach(tptr, mptr);
}
}
}
/**
* Attach a callback called when a packet is received
*
* @param ptr function pointer
*/
inline void attach(void (*fn)(void), IrqType irq = RxIrq) {
if (fn != NULL) {
if (irq == RxIrq) {
rx.attach(fn);
} else {
tx.attach(fn);
}
}
}
/** Set the baud rate of the serial port
*
* @param baudrate The baudrate of the serial port (default = 9600).
*/
void baud(int baudrate = 9600);
/** Set the transmission format used by the Serial port
*
* @param bits The number of bits in a word (default = 8)
* @param parity The parity used (USBHostSerialPort::None, USBHostSerialPort::Odd, USBHostSerialPort::Even, USBHostSerialPort::Mark, USBHostSerialPort::Space; default = USBHostSerialPort::None)
* @param stop The number of stop bits (1 or 2; default = 1)
*/
void format(int bits = 8, Parity parity = USBHostSerialPort::None, int stop_bits = 1);
virtual int writeBuf(const char* b, int s);
virtual int readBuf(char* b, int s);
protected:
virtual int _getc();
virtual int _putc(int c);
private:
USBHost * host;
USBDeviceConnected * dev;
USBEndpoint * bulk_in;
USBEndpoint * bulk_out;
uint32_t size_bulk_in;
uint32_t size_bulk_out;
void init();
MtxCircBuffer<uint8_t, 128> circ_buf;
uint8_t buf[64];
typedef struct {
uint32_t baudrate;
uint8_t stop_bits;
uint8_t parity;
uint8_t data_bits;
} PACKED LINE_CODING;
LINE_CODING line_coding;
void rxHandler();
void txHandler();
FunctionPointer rx;
FunctionPointer tx;
uint8_t serial_intf;
};
#if (USBHOST_SERIAL <= 1)
class USBHostSerial : public IUSBEnumerator, public USBHostSerialPort
{
public:
USBHostSerial();
/**
* Try to connect a serial device
*
* @return true if connection was successful
*/
bool connect();
void disconnect();
/**
* Check if a any serial port is connected
*
* @returns true if a serial device is connected
*/
bool connected();
protected:
USBHost* host;
USBDeviceConnected* dev;
uint8_t port_intf;
int ports_found;
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
bool dev_connected;
};
#else // (USBHOST_SERIAL > 1)
class USBHostMultiSerial : public IUSBEnumerator {
public:
USBHostMultiSerial();
virtual ~USBHostMultiSerial();
USBHostSerialPort* getPort(int port)
{
return port < USBHOST_SERIAL ? ports[port] : NULL;
}
/**
* Try to connect a serial device
*
* @return true if connection was successful
*/
bool connect();
void disconnect();
/**
* Check if a any serial port is connected
*
* @returns true if a serial device is connected
*/
bool connected();
protected:
USBHost* host;
USBDeviceConnected* dev;
USBHostSerialPort* ports[USBHOST_SERIAL];
uint8_t port_intf[USBHOST_SERIAL];
int ports_found;
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
bool dev_connected;
};
#endif // (USBHOST_SERIAL <= 1)
#endif
#endif