/*
 FX2 firmware: common setup functions
 
 Copyright (c) 2008 Dimtel, Inc., All Rights Reserved

 $Id: vendor.c,v 1.1 2012/11/11 01:24:33 dim Exp $
 $Date: 2012/11/11 01:24:33 $
 $Author: dim $
 $Revision: 1.1 $
 $Log: vendor.c,v $
 Revision 1.1  2012/11/11 01:24:33  dim
 Moved from BxB, adapted to compile for both LLRF4 and IGP12

 Revision 1.1  2011/12/27 19:31:48  dim
 Updated to remove deprecated constructs (at, sfr, xdata, sbit)


*/

#include "fx2regs.h"
#include "common.h"
#include "usb.h"
#include "jtag.h"
#include "i2c.h"
#include "vendor.h"
#include "hwdef.h"
#include "../include/usb_defs.h"
#include "../include/vendor_commands.h"

char vendor_cmd_handler(void)
{
  uchar len;
  setupdata *setup = (setupdata *)SETUPDAT;
  
  if (setup->bmRequestType & USB_DIR_IN)
  {
    /* IN request */
    switch (setup->bmRequest)
    {
      case USB_REQ_VENDOR_I2C_READ:
        if (!i2c_read(setup->wValueL, EP0BUF, setup->wLengthL))
          return 0;
        len = setup->wLengthL;
        break;
      case USB_REQ_VENDOR_JTAG_RXTX:
        *EP0BUF = jtag_rxtx(setup->wValueL);
        len = 1;
        break;
      case USB_REQ_VENDOR_GET_STATUS:
        /* Read error counter */
        *EP0BUF = ERRCNTLIM >> 4;
        /* Reset the counter */
        CLRERRCNT = 0;
        len = 1;
        break;
      default:
        return 0;
    }
    /* Send back the result */
    EP0BCH = 0;
    EP0BCL = len;
  }
  else
    /* OUT request */
    switch (setup->bmRequest)
    {
      case USB_REQ_VENDOR_JTAG:	/* Subcommands just for xguff compatibility */
        switch(setup->wIndexL)
        {
          case JTAG_FLAG_BLOCK:
            poll_ep0();
            jtag_block_write(EP0BUF, EP0BCL);
            break;
          case JTAG_FLAG_INIT: /* Do nothing */
            break;
          default:
            return 0;
        }
        break;
      case USB_REQ_VENDOR_I2C_WRITE:
        poll_ep0();
        if (!i2c_write(setup->wValueL, EP0BUF, EP0BCL))
          return 0;
        break;
      case USB_REQ_VENDOR_FPGA_RESET:
        fpga_reset();
        break;
      default:
        return 0;
    }
  
  return 1;
}
