/* drivers/dfu/usb/dfu/dfustate.h
 *
 * (c) 2002 Simtec Electronics
 *
 * Ben Dooks
 *
 * USB DFU Class - state of an upload / download / etc
 *
 * $Id: dfustate.h,v 1.10 2003/08/08 10:19:17 ben Exp $
 *
 * This Library file is part of the Simtec Electronics USB stack development
 *   suite.
 * Specific licence is granted to use this file by third parties for the
 *   development of USB device drivers.
*/

#ifndef __USB_DFU_DFUSTATE_H
#define __USB_DFU_DFUSTATE_H "$Id: dfustate.h,v 1.10 2003/08/08 10:19:17 ben Exp $"

enum usbdfu_op {
  DFUOP_NONE                = 0x00,   /* no state */
  DFUOP_INIT                = 0x01,   /* first state in machine */
  DFUOP_GETSTATE            = 0x02,   /* issued GetState and awaiting reply */
  DFUOP_GETFNDESCRIPTOR     = 0x03,   /* awaiting function descriptor */
  DFUOP_AWAITWRITE          = 0x04,   /* awaiting user to write data */
  DFUOP_WRITEBLOCK          = 0x05,   /* got block, need to send */
  DFUOP_WRITTENBLOCK        = 0x06,   /* sent block, awaiting finish */
  DFUOP_GETSTATUS           = 0x07,   /* getting status (GetStatus) call */
  DFUOP_RESET1              = 0x08,   /* sent first reset */
  DFUOP_RESET2              = 0x09,   /* completed reset */
  DFUOP_DONE                = 0x0A    /* done */
};

typedef enum usbdfu_op usbdfu_op_t;

/* see usbdfu spec, page19 */

enum usbdfu_devstate_e {
  USBDFU_DEVSTATE_NONE = -1,            /* no state at-all */
  USBDFU_DEVSTATE_appIDLE = 0,          /* app running in standard mode */
  USBDFU_DEVSTATE_appDETACH = 1,        /* receive detach request */
  USBDFU_DEVSTATE_dfuIDLE = 2,          /* idling in dfu mode */
  USBDFU_DEVSTATE_dfuDNLOAD_SYNC = 3,   /* got block and awaiting getstatus */
  USBDFU_DEVSTATE_dfuDNBUSY = 4,        /* processing downloaded block */
  USBDFU_DEVSTATE_dfuDNLOAD_IDLE = 5,   /* download idle */  
  USBDFU_DEVSTATE_dfuMANIFEST_SYNC = 6, /* final block */
  USBDFU_DEVSTATE_dfuMANIFEST = 7,
  USBDFU_DEVSTATE_dfuMANIFEST_WAITRESET = 8,
  USBDFU_DEVSTATE_dfuUPLOAD_IDLE = 9,
  USBDFU_DEVSTATE_dfuERROR = 10,

  /* meta-states for various operations */
  USBDFU_DEVSTATE_dfuRESETGUARD = 0x10000
};

typedef enum usbdfu_devstate_e usbdfu_devstate_t;

typedef struct usbdfu_state_s usbdfu_state_t;

#define USB_DFU_MAGIC "UDFU"

struct usbdfu_state_s {
  unsigned char          magic[4];      /* magic identity for checks, etc */

  usbdfu_op_t            op;            /* current operation */
  usbdfu_devstate_t      state;         /* last reported status from device */

  void                   *pw;           /* private word for user */

  unsigned char          status[6];     /* last status response */

  unsigned int           iface;         /* interface for the device */
  unsigned int           blksize;       /* size of a block for the device */

  struct usbmsg_new_device *devmsg;     /* device message used */

  usb_device_t           device;        /* device we've attached to */
  usb_endpoint_t         ep;            /* default endpoint */
  usb_pipe_t             *pipe;         /* pipe we're using */

  usb_buffer_t           *data;         /* buffer for the data */
  usb_buffer_t           *req;          /* buffer for request */

  usb_wait_t             *usewait;      /* waiting to use to start reqs */
  usb_wait_t             *wait;         /* current waiting */

  int                    count;         /* number of bytes moved */
  int                    ptr;           /* current request pointer */

  unsigned char          fn_descr[8];   /* function descriptor */
};

#endif /* __USB_DFU_DFUSTATE_H */
