/**
 * \file
 *
 * \brief SAM USB device HAL
 *
 * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Subject to your compliance with these terms, you may use Microchip
 * software and any derivatives exclusively with Microchip products.
 * It is your responsibility to comply with third party license terms applicable
 * to your use of third party software (including open source software) that
 * may accompany Microchip software.
 *
 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT
 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
 *
 * \asf_license_stop
 *
 */

#include "hal_usb_device.h"
#include "hal_atomic.h"

#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

/** USB device HAL driver version. */
#define USB_D_VERSION 0x00000001u

/**
 *  Endpoint callbacks for data transfer.
 */
struct usb_d_ep_callbacks {
	/** Callback that is invoked when setup packet is received. */
	usb_d_ep_cb_setup_t req;
	/** Callback invoked when buffer is done, but last packet is full size
	 *  packet without ZLP. Return \c true if new transfer has been submitted.
	 */
	usb_d_ep_cb_more_t more;
	/** Callback invoked when transfer is finished/halted/aborted or error
	 *  occurs.
	 */
	usb_d_ep_cb_xfer_t xfer;
};

/**
 *  Endpoint transfer descriptor header.
 */
struct usb_ep_xfer_hdr {
	/** Transfer type, reuse \ref usb_ep_type. */
	uint8_t type;
	/** Endpoint address. */
	uint8_t ep;
	/** Endpoint state. */
	uint8_t state;
	/** Last status code. */
	uint8_t status;
};

/**
 *  Transfer descriptor.
 */
struct usb_ep_xfer {
	/** General transfer descriptor. */
	struct usb_ep_xfer_hdr hdr;
	/** Pointer to data buffer. */
	uint8_t *buf;
	/** Transfer size. */
	uint32_t size;
	/** Control request packet. */
	uint8_t req[8];
};

/**
 *  USB device endpoint descriptor.
 */
struct usb_d_ep {
	/** On-going transfer on the endpoint. */
	struct usb_ep_xfer xfer;
	/** Endpoint callbacks. */
	struct usb_d_ep_callbacks callbacks;
};

/**
 *  USB device HAL driver descriptor.
 */
struct usb_d_descriptor {
	/** USB device endpoints. */
	struct usb_d_ep ep[CONF_USB_D_NUM_EP_SP];
};

/** The USB HAL driver descriptor instance. */
static struct usb_d_descriptor usb_d_inst;

/** \brief Find the endpoint.
 * \param[in] ep Endpoint address.
 * \return Index of endpoint descriptor.
 * \retval >=0 The index.
 * \retval <0 Not found (endpoint is not initialized).
 */
static int8_t _usb_d_find_ep(const uint8_t ep)
{
	int8_t i;
	for (i = 0; i < CONF_USB_D_NUM_EP_SP; i++) {
		if (usb_d_inst.ep[i].xfer.hdr.ep == ep) {
			return i;
		}
		if (usb_d_inst.ep[i].xfer.hdr.type == USB_EP_XTYPE_CTRL
		    && (ep & USB_EP_N_MASK) == usb_d_inst.ep[i].xfer.hdr.ep) {
			return i;
		}
	}
	return -1;
}

/**
 * \brief Start transactions
 * \param[in] ep Endpoint address.
 * \param[in] dir Endpoint transfer direction.
 * \param[in] buf Pointer to transfer buffer.
 * \param[in] size Transfer size.
 * \param[in] zlp Auto append ZLP for IN, or wait ZLP for OUT.
 */
static inline int32_t _usb_d_trans(const uint8_t ep, const bool dir, const uint8_t *buf, const uint32_t size,
                                   const uint8_t zlp)
{
	struct usb_d_transfer trans
	    = {(uint8_t *)buf, size, dir ? (uint8_t)(ep | USB_EP_DIR) : (uint8_t)(ep & USB_EP_N_MASK), zlp};

	return _usb_d_dev_ep_trans(&trans);
}

/**
 * \brief Dummy callback that returns false
 * \param[in] unused0 Unused parameter.
 * \param[in] unused1 Unused parameter.
 * \param[in] unused2 Unused parameter.
 * \return Always \c false.
 */
static bool usb_d_dummy_cb_false(uint32_t unused0, uint32_t unused1, uint32_t unused2)
{
	(void)unused0;
	(void)unused1;
	(void)unused2;
	return false;
}

/**
 * \brief Callback invoked when SETUP packet is ready
 * \param[in] ep Endpoint number with transfer direction on bit 8.
 */
static void usb_d_cb_trans_setup(const uint8_t ep)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	uint8_t *        req      = ept->xfer.req;

	uint8_t n = _usb_d_dev_ep_read_req(ep, req);
	if (n != 8) {
		_usb_d_dev_ep_stall(ep, USB_EP_STALL_SET);
		_usb_d_dev_ep_stall(ep | USB_EP_DIR, USB_EP_STALL_SET);
		return;
	}

	_usb_d_dev_ep_stall(ep, USB_EP_STALL_CLR);
	_usb_d_dev_ep_stall(ep | USB_EP_DIR, USB_EP_STALL_CLR);
	ept->xfer.hdr.state = USB_EP_S_IDLE;
	if (!ept->callbacks.req(ep, req)) {
		ept->xfer.hdr.state = USB_EP_S_HALTED;
		_usb_d_dev_ep_stall(ep, USB_EP_STALL_SET);
		_usb_d_dev_ep_stall(ep | USB_EP_DIR, USB_EP_STALL_SET);
	}
}

/**
 * \brief Callback invoked when request more data
 * \param[in] ep Endpoint number with transfer direction on bit 8.
 * \param[in] transfered Number of bytes transfered.
 */
static bool usb_d_cb_trans_more(const uint8_t ep, const uint32_t transfered)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	if (ept->xfer.hdr.state == USB_EP_S_X_DATA) {
		return ept->callbacks.more(ep, transfered);
	}
	return false;
}

/**
 * \brief Handles the case that control endpoint transactions are done
 * \param[in,out] ept Pointer to endpoint information.
 */
static inline void usb_d_ctrl_trans_done(struct usb_d_ep *ept)
{
	uint8_t state   = ept->xfer.hdr.state;
	bool    req_dir = USB_GET_bmRequestType(ept->xfer.req) & USB_REQ_TYPE_IN;

	if (state == USB_EP_S_X_DATA) {
		/* Data stage -> Status stage */
		bool err = ept->callbacks.xfer(ept->xfer.hdr.ep, USB_XFER_DATA, ept->xfer.req);
		if (err) {
			ept->xfer.hdr.state  = USB_EP_S_HALTED;
			ept->xfer.hdr.status = USB_XFER_HALT;
			_usb_d_dev_ep_stall(req_dir ? ept->xfer.hdr.ep : (ept->xfer.hdr.ep | USB_EP_DIR), USB_EP_STALL_SET);
		} else {
			ept->xfer.hdr.state = USB_EP_S_X_STATUS;
			_usb_d_trans(ept->xfer.hdr.ep, !req_dir, NULL, 0, 1);
		}
	} else {
		/* Status stage done */
		ept->callbacks.xfer(ept->xfer.hdr.ep, USB_XFER_DONE, ept->xfer.req);
		ept->xfer.hdr.state = USB_EP_S_X_SETUP;
	}
}

/**
 * Callback when USB transactions are finished.
 */
static void _usb_d_cb_trans_done(const uint8_t ep, const int32_t code, const uint32_t transferred)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];

	if (code == USB_TRANS_DONE) {
		ept->xfer.hdr.status = USB_XFER_DONE;
		if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) {
			usb_d_ctrl_trans_done(ept);
			return;
		}
		ept->xfer.hdr.state = USB_EP_S_IDLE;
	} else if (code == USB_TRANS_STALL) {
		ept->xfer.hdr.status = USB_XFER_HALT;
		if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) {
			ept->xfer.hdr.state = USB_EP_S_X_SETUP;
			_usb_d_dev_ep_stall(ep, USB_EP_STALL_CLR);
		} else {
			ept->xfer.hdr.state = USB_EP_S_HALTED;
		}
	} else if (code == USB_TRANS_ABORT) {
		ept->xfer.hdr.status = USB_XFER_ABORT;
		if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) {
			ept->xfer.hdr.state = USB_EP_S_X_SETUP;
			return;
		}
		ept->xfer.hdr.state = USB_EP_S_IDLE;
	} else if (code == USB_TRANS_RESET) {
		ept->xfer.hdr.state  = USB_EP_S_DISABLED;
		ept->xfer.hdr.status = USB_XFER_RESET;
	} else {
		ept->xfer.hdr.state  = USB_EP_S_ERROR;
		ept->xfer.hdr.status = USB_XFER_ERROR;
	}

	ept->callbacks.xfer(ep, (enum usb_xfer_code)ept->xfer.hdr.status, (void *)transferred);
}

int32_t usb_d_init(void)
{
	int32_t rc = _usb_d_dev_init();
	uint8_t i;
	if (rc < 0) {
		return rc;
	}
	memset(usb_d_inst.ep, 0x00, sizeof(struct usb_d_ep) * CONF_USB_D_NUM_EP_SP);
	for (i = 0; i < CONF_USB_D_NUM_EP_SP; i++) {
		usb_d_inst.ep[i].xfer.hdr.ep    = 0xFF;
		usb_d_inst.ep[i].callbacks.req  = (usb_d_ep_cb_setup_t)usb_d_dummy_cb_false;
		usb_d_inst.ep[i].callbacks.more = (usb_d_ep_cb_more_t)usb_d_dummy_cb_false;
		usb_d_inst.ep[i].callbacks.xfer = (usb_d_ep_cb_xfer_t)usb_d_dummy_cb_false;
	}
	/* Handles device driver endpoint callbacks to build transfer. */
	_usb_d_dev_register_ep_callback(USB_D_DEV_EP_CB_SETUP, (FUNC_PTR)usb_d_cb_trans_setup);
	_usb_d_dev_register_ep_callback(USB_D_DEV_EP_CB_MORE, (FUNC_PTR)usb_d_cb_trans_more);
	_usb_d_dev_register_ep_callback(USB_D_DEV_EP_CB_DONE, (FUNC_PTR)_usb_d_cb_trans_done);
	return ERR_NONE;
}

void usb_d_deinit(void)
{
	_usb_d_dev_deinit();
}

void usb_d_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func)
{
	/* Directly uses device driver callback. */
	_usb_d_dev_register_callback(type, func);
}

int32_t usb_d_enable(void)
{
	return _usb_d_dev_enable();
}

void usb_d_disable(void)
{
	_usb_d_dev_disable();
}

void usb_d_attach(void)
{
	_usb_d_dev_attach();
}

void usb_d_detach(void)
{
	_usb_d_dev_detach();
}

enum usb_speed usb_d_get_speed(void)
{
	return _usb_d_dev_get_speed();
}

uint16_t usb_d_get_frame_num(void)
{
	return _usb_d_dev_get_frame_n();
}

uint8_t usb_d_get_uframe_num(void)
{
	return _usb_d_dev_get_uframe_n();
}

void usb_d_set_address(const uint8_t addr)
{
	_usb_d_dev_set_address(addr);
}

void usb_d_send_remotewakeup(void)
{
	_usb_d_dev_send_remotewakeup();
}

int32_t usb_d_ep0_init(const uint8_t max_pkt_size)
{
	return usb_d_ep_init(0, USB_EP_XTYPE_CTRL, max_pkt_size);
}

int32_t usb_d_ep_init(const uint8_t ep, const uint8_t attr, const uint16_t max_pkt_size)
{
	int32_t          rc;
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	if (ep_index >= 0) {
		return -USB_ERR_REDO;
	} else {
		ep_index = _usb_d_find_ep(0xFF);
		if (ep_index < 0) {
			return -USB_ERR_ALLOC_FAIL;
		}
		ept = &usb_d_inst.ep[ep_index];
	}
	rc = _usb_d_dev_ep_init(ep, attr, max_pkt_size);
	if (rc < 0) {
		return rc;
	}
	ept->xfer.hdr.ep   = ep;
	ept->xfer.hdr.type = attr & USB_EP_XTYPE_MASK;
	return ERR_NONE;
}

void usb_d_ep_deinit(const uint8_t ep)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	if (ep_index < 0) {
		return;
	}
	_usb_d_dev_ep_deinit(ep);
	ept->xfer.hdr.ep = 0xFF;
}

int32_t usb_d_ep_enable(const uint8_t ep)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	int32_t          rc;
	if (ep_index < 0) {
		return -USB_ERR_PARAM;
	}
	ept->xfer.hdr.state = (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) ? USB_EP_S_X_SETUP : USB_EP_S_IDLE;
	rc                  = _usb_d_dev_ep_enable(ep);
	if (rc < 0) {
		ept->xfer.hdr.state = USB_EP_S_DISABLED;
	}
	return rc;
}

void usb_d_ep_disable(const uint8_t ep)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	if (ep_index < 0) {
		return;
	}
	_usb_d_dev_ep_disable(ep);
	ept->xfer.hdr.state = USB_EP_S_DISABLED;
}

uint8_t *usb_d_ep_get_req(const uint8_t ep)
{
	int8_t ep_index = _usb_d_find_ep(ep);
	if (ep_index < 0) {
		return NULL;
	}
	return usb_d_inst.ep[ep_index].xfer.req;
}

int32_t usb_d_ep_transfer(const struct usb_d_transfer *xfer)
{
	int8_t                ep_index = _usb_d_find_ep(xfer->ep);
	struct usb_d_ep *     ept      = &usb_d_inst.ep[ep_index];
	bool                  dir = USB_EP_GET_DIR(xfer->ep), zlp = xfer->zlp;
	uint32_t              len = xfer->size;
	int32_t               rc;
	volatile uint8_t      state;
	volatile hal_atomic_t flags;

	if (ep_index < 0) {
		return -USB_ERR_PARAM;
	}

	atomic_enter_critical(&flags);
	state = ept->xfer.hdr.state;
	if (state == USB_EP_S_IDLE) {
		ept->xfer.hdr.state = USB_EP_S_X_DATA;
		atomic_leave_critical(&flags);
	} else {
		atomic_leave_critical(&flags);
		switch (state) {
		case USB_EP_S_HALTED:
			return USB_HALTED;
		case USB_EP_S_ERROR:
			return -USB_ERROR;
		case USB_EP_S_DISABLED:
			return -USB_ERR_FUNC;
		default: /* USB_EP_S_X_xxxx  */
			return USB_BUSY;
		}
	}

	if (ept->xfer.hdr.type == USB_EP_XTYPE_CTRL) {
		uint16_t req_len = USB_GET_wLength(ept->xfer.req);
		/* SETUP without data: ZLP IN as status. */
		if (req_len == 0) {
			dir                 = true;
			len                 = 0;
			zlp                 = true;
			ept->xfer.hdr.state = USB_EP_S_X_STATUS;
		} else {
			dir = (USB_GET_bmRequestType(ept->xfer.req) & USB_REQ_TYPE_IN);
			/* Data length not exceed requested. */
			if (len > req_len) {
				len = req_len;
			}
			if (dir) {
				/* Setup -> In */
				zlp = (req_len > len);
			} else {
				zlp = false;
			}
		}
	}

	rc = _usb_d_trans(xfer->ep, dir, xfer->buf, len, zlp);
	return rc;
}

void usb_d_ep_abort(const uint8_t ep)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	if (ep_index < 0) {
		return;
	}
	_usb_d_dev_ep_abort(ep);
	ept->xfer.hdr.state  = USB_EP_S_IDLE;
	ept->xfer.hdr.status = USB_XFER_ABORT;
}

int32_t usb_d_ep_get_status(const uint8_t ep, struct usb_d_ep_status *stat)
{
	int8_t                    ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *         ept      = &usb_d_inst.ep[ep_index];
	struct usb_d_trans_status tmp;
	uint8_t                   state = ept->xfer.hdr.state;
	if (ep_index < 0) {
		return -USB_ERR_PARAM;
	}
	if (stat) {
		/* Check transaction status if transferring data. */
		_usb_d_dev_ep_get_status(ep, &tmp);
		stat->ep    = ep;
		stat->state = state;
		stat->code  = ept->xfer.hdr.status;
		stat->count = tmp.count;
		stat->size  = tmp.size;
	}
	switch (state) {
	case USB_EP_S_IDLE:
		return USB_OK;
	case USB_EP_S_HALTED:
		return USB_HALTED;
	case USB_EP_S_ERROR:
		return -USB_ERROR;
	case USB_EP_S_DISABLED:
		return -USB_ERR_FUNC;
	default:
		/* Busy */
		return USB_BUSY;
	}
}

static inline int32_t _usb_d_ep_halt_clr(const uint8_t ep)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	int32_t          rc;
	if (ep_index < 0) {
		return -USB_ERR_PARAM;
	}
	if (_usb_d_dev_ep_stall(ep, USB_EP_STALL_GET)) {
		rc = _usb_d_dev_ep_stall(ep, USB_EP_STALL_CLR);
		if (rc < 0) {
			return rc;
		}
		ept->xfer.hdr.state  = USB_EP_S_IDLE;
		ept->xfer.hdr.status = USB_XFER_UNHALT;
		ept->callbacks.xfer(ep, USB_XFER_UNHALT, NULL);
	}
	return ERR_NONE;
}

int32_t usb_d_ep_halt(const uint8_t ep, const enum usb_ep_halt_ctrl ctrl)
{
	if (ctrl == USB_EP_HALT_CLR) {
		return _usb_d_ep_halt_clr(ep);
	} else if (ctrl == USB_EP_HALT_SET) {
		return _usb_d_dev_ep_stall(ep, USB_EP_STALL_SET);
	} else {
		return _usb_d_dev_ep_stall(ep, USB_EP_STALL_GET);
	}
}

void usb_d_ep_register_callback(const uint8_t ep, const enum usb_d_ep_cb_type type, const FUNC_PTR func)
{
	int8_t           ep_index = _usb_d_find_ep(ep);
	struct usb_d_ep *ept      = &usb_d_inst.ep[ep_index];
	FUNC_PTR         f        = func ? (FUNC_PTR)func : (FUNC_PTR)usb_d_dummy_cb_false;
	if (ep_index < 0) {
		return;
	}
	switch (type) {
	case USB_D_EP_CB_SETUP:
		ept->callbacks.req = (usb_d_ep_cb_setup_t)f;
		break;
	case USB_D_EP_CB_MORE:
		ept->callbacks.more = (usb_d_ep_cb_more_t)f;
		break;
	case USB_D_EP_CB_XFER:
		ept->callbacks.xfer = (usb_d_ep_cb_xfer_t)f;
		break;
	default:
		break;
	}
}

uint32_t usb_d_get_version(void)
{
	return USB_D_VERSION;
}

#ifdef __cplusplus
}
#endif
