Skip to content

Add USB Device implementation, fix a bug for serial #10712

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*!
\file drv_usb_core.h
\brief USB core low level driver header file

\version 2018-10-08, V1.0.0, firmware for GD32 USBFS&USBHS
*/

/*
Copyright (c) 2018, GigaDevice Semiconductor Inc.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#ifndef __DRV_USB_CORE_H
#define __DRV_USB_CORE_H

#ifdef __cplusplus
extern "C" {
#endif

#include "drv_usb_regs.h"

#define USB_FS_EP0_MAX_LEN 64U /* maximum packet size of EndPoint0 */

#define HC_MAX_PACKET_COUNT 140U /* maximum packet count */

#define EP_ID(x) ((uint8_t)((x) & 0x7FU)) /* endpoint number */
#define EP_DIR(x) ((uint8_t)((x) >> 7)) /* endpoint direction */

enum _usb_eptype {
USB_EPTYPE_CTRL = 0U, /*!< control endpoint type */
USB_EPTYPE_ISOC = 1U, /*!< isochronous endpoint type */
USB_EPTYPE_BULK = 2U, /*!< bulk endpoint type */
USB_EPTYPE_INTR = 3U, /*!< interrupt endpoint type */
USB_EPTYPE_MASK = 3U, /*!< endpoint type mask */
};

typedef enum {
USB_OTG_OK = 0, /*!< USB OTG status OK*/
USB_OTG_FAIL /*!< USB OTG status fail*/
} usb_otg_status;

typedef enum {
USB_OK = 0, /*!< USB status OK*/
USB_FAIL /*!< USB status fail*/
} usb_status;

typedef enum {
USB_USE_FIFO, /*!< USB use FIFO transfer mode */
USB_USE_DMA /*!< USB use DMA transfer mode */
} usb_transfer_mode;

typedef struct {
uint8_t core_enum; /*!< USB core type */
uint8_t core_speed; /*!< USB core speed */
uint8_t num_pipe; /*!< USB host channel numbers */
uint8_t num_ep; /*!< USB device endpoint numbers */
uint8_t transfer_mode; /*!< USB transfer mode */
uint8_t phy_itf; /*!< USB core PHY interface */
uint8_t sof_enable; /*!< USB SOF output */
uint8_t low_power; /*!< USB low power */
} usb_core_basic;

/* function declarations */

/* config core capabilities */
usb_status usb_basic_init(const usb_core_basic usb_basic, usb_core_regs *usb_regs);

/*initializes the USB controller registers and prepares the core device mode or host mode operation*/
usb_status usb_core_init(usb_core_basic usb_basic, usb_core_regs *usb_regs);

/* read a packet from the Rx FIFO associated with the endpoint */
void *usb_rxfifo_read(usb_core_regs *core_regs, uint8_t *dest_buf, uint16_t byte_count);

/* write a packet into the Tx FIFO associated with the endpoint */
usb_status usb_txfifo_write(usb_core_regs *usb_regs,
uint8_t *src_buf,
uint8_t fifo_num,
uint16_t byte_count);

/* flush a Tx FIFO or all Tx FIFOs */
usb_status usb_txfifo_flush(usb_core_regs *usb_regs, uint8_t fifo_num);

/* flush the entire Rx FIFO */
usb_status usb_rxfifo_flush(usb_core_regs *usb_regs);

void usb_set_rxfifo(usb_core_regs *usb_regs, uint16_t size);

void usb_set_txfifo(usb_core_regs *usb_regs, uint8_t fifo, uint16_t size);

/* get the global interrupts */
static inline uint32_t usb_coreintr_get(usb_core_regs *usb_regs)
{
return usb_regs->gr->GINTEN & usb_regs->gr->GINTF;
}

#ifdef __cplusplus
}
#endif

#endif /* __DRV_USB_CORE_H */
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*!
\file drv_usb_dev.h
\brief USB device low level driver header file

\version 2018-10-08, V1.0.0, firmware for GD32 USBFS&USBHS
*/

/*
Copyright (c) 2018, GigaDevice Semiconductor Inc.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#ifndef __DRV_USB_DEV_H
#define __DRV_USB_DEV_H

#ifdef __cplusplus
extern "C" {
#endif

#include "drv_usb_core.h"

enum usb_ctl_status {
USB_CTL_IDLE = 0U, /*!< USB control transfer idle state */
USB_CTL_DATA_IN, /*!< USB control transfer data in state */
USB_CTL_LAST_DATA_IN, /*!< USB control transfer last data in state */
USB_CTL_DATA_OUT, /*!< USB control transfer data out state */
USB_CTL_LAST_DATA_OUT, /*!< USB control transfer last data out state */
USB_CTL_STATUS_IN, /*!< USB control transfer status in state*/
USB_CTL_STATUS_OUT /*!< USB control transfer status out state */
};

#define USB_MIN(a, b) (((a) < (b)) ? (a) : (b))

#define EP_IN(x) ((uint8_t)(0x80U | (x))) /*!< device IN endpoint */
#define EP_OUT(x) ((uint8_t)(x)) /*!< device OUT endpoint */

#pragma pack(1)

/* USB standard device request structure */
typedef struct _usb_req {
uint8_t bmRequestType; /*!< type of request */
uint8_t bRequest; /*!< request of setup packet */
uint16_t wValue; /*!< value of setup packet */
uint16_t wIndex; /*!< index of setup packet */
uint16_t wLength; /*!< length of setup packet */
} usb_req;

#pragma pack()

/* USB power management */
typedef struct _usb_pm {
uint8_t power_mode; /*!< power mode */
uint8_t power_low; /*!< power low */
uint8_t dev_remote_wakeup; /*!< remote wakeup */
uint8_t remote_wakeup_on; /*!< remote wakeup on */
} usb_pm;

typedef struct {
struct {
uint8_t num: 4; /*!< the endpoint number.it can be from 0 to 6 */
uint8_t pad: 3; /*!< padding between number and direction */
uint8_t dir: 1; /*!< the endpoint direction */
} ep_addr;

uint8_t ep_type; /*!< USB endpoint type */
uint8_t ep_stall; /*!< USB endpoint stall status */

uint8_t frame_num; /*!< number of frame */
uint16_t max_len; /*!< Maximum packet lenth */

/* transaction level variables */
uint8_t *xfer_buf; /*!< transmit buffer */
uint32_t xfer_len; /*!< transmit buffer length */
uint32_t xfer_count; /*!< transmit buffer count */

uint32_t remain_len; /*!< remain packet lenth */

uint32_t dma_addr; /*!< DMA address */
} usb_transc;

typedef struct _usb_core_driver usb_dev;

typedef struct _usb_class_core {
uint8_t command; /*!< device class request command */
uint8_t alter_set; /*!< alternative set */

uint8_t (*init)(usb_dev *udev, uint8_t config_index); /*!< initialize handler */
uint8_t (*deinit)(usb_dev *udev, uint8_t config_index); /*!< de-initialize handler */

uint8_t (*req_proc)(usb_dev *udev, usb_req *req); /*!< device request handler */

uint8_t (*data_in)(usb_dev *udev, uint8_t ep_num); /*!< device data in handler */
uint8_t (*data_out)(usb_dev *udev, uint8_t ep_num); /*!< device data out handler */

uint8_t (*SOF)(usb_dev *udev); /*!< Start of frame handler */

uint8_t (*incomplete_isoc_in)(usb_dev *udev); /*!< Incomplete synchronization IN transfer handler */
uint8_t (*incomplete_isoc_out)(usb_dev *udev); /*!< Incomplete synchronization OUT transfer handler */
} usb_class_core;

typedef struct _usb_perp_dev {
uint8_t config; /*!< configuration */
uint8_t dev_addr; /*!< device address */

__IO uint8_t cur_status; /*!< current status */
__IO uint8_t backup_status; /*!< backup status */

usb_transc transc_in[USBFS_MAX_TX_FIFOS]; /*!< endpoint IN transaction */
usb_transc transc_out[USBFS_MAX_TX_FIFOS]; /*!< endpoint OUT transaction */

// usb_pm pm; /*!< power management */
uint32_t setup[12];

usb_class_core *class_core; /*!< class driver */
} usb_perp_dev;

typedef struct _usb_core_driver {
usb_core_basic bp; /*!< USB basic parameters */
usb_core_regs regs; /*!< USB registers */
usb_perp_dev dev; /*!< USB peripheral device */
void *pData; /*!< USB internal data */
} usb_core_driver;

/* function declarations */

/* initialize USB core registers for device mode */
usb_status usb_devcore_init(usb_core_driver *udev);

usb_status usb_globalint_disable(usb_core_driver *udev);

usb_status usb_globalint_enable(usb_core_driver *udev);

/* enable the USB device mode interrupts */
usb_status usb_devint_enable(usb_core_driver *udev);

/* active the usb transaction */
usb_status usb_transc_active(usb_core_driver *udev, usb_transc *transc);

/* deactive the usb transaction */
usb_status usb_transc_deactivate(usb_core_driver *udev, usb_transc *transc);

/* configure usb transaction to start IN transfer */
usb_status usb_transc_inxfer(usb_core_driver *udev, usb_transc *transc);

/* configure usb transaction to start OUT transfer */
usb_status usb_transc_outxfer(usb_core_driver *udev, usb_transc *transc);

/* set the usb transaction STALL status */
usb_status usb_transc_stall(usb_core_driver *udev, usb_transc *transc);

/* clear the usb transaction STALL status */
usb_status usb_transc_clrstall(usb_core_driver *udev, usb_transc *transc);

/* read device all OUT endpoint interrupt register */
uint32_t usb_oepintnum_read(usb_core_driver *udev);

/* read device OUT endpoint interrupt flag register */
uint32_t usb_oepintr_read(usb_core_driver *udev, uint8_t ep_num);

/* read device all IN endpoint interrupt register */
uint32_t usb_iepintnum_read(usb_core_driver *udev);

/* read device IN endpoint interrupt flag register */
uint32_t usb_iepintr_read(usb_core_driver *udev, uint8_t ep_num);

/* config the USB device to be disconnected */
void usb_dev_disconnect(usb_core_driver *udev);

/* config the USB device to be connected */
void usb_dev_connect(usb_core_driver *udev);

/* set the USB device address */
void usb_devaddr_set(usb_core_driver *pudev, uint8_t dev_addr);

/* configures OUT endpoint 0 to receive SETUP packets */
void usb_ctlep_startout(usb_core_driver *udev);

/* active remote wakeup signalling */
void usb_rwkup_active(usb_core_driver *udev);

/* reset remote wakeup signalling */
void usb_rwkup_reset(usb_core_driver *udev);

/* set remote wakeup signalling */
void usb_rwkup_set(usb_core_driver *udev);

/* active USB core clock */
void usb_clock_active(usb_core_driver *udev);

/* usb device suspend */
void usb_dev_suspend(usb_core_driver *udev);

/* stop the device and clean up fifos */
void usb_dev_stop(usb_core_driver *udev);

#ifdef __cplusplus
}
#endif

#endif /* __DRV_USB_DEV_H */

Loading