/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *                                        *
 *    Copyright (C) 1987, 1991 by John E. Lloyd.                *
 *                                        *
 *    Information on copyright permissions, as well as a complete        *
 *    disclaimer of warranty, is given in the file COPYRIGHT.            *
 *                                        *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
 *   - Declares/Defines functions/Macros to manage the device by the user application: open device, read and write data
 *   - Define ancillary structure and MaCROS to be used by the HAL runtime environment for device initalization.
 */

#ifndef _GPIO_DRV11J_H_
#define _GPIO_DRV11J_H_


#include <stddef.h>

#include "sys/alt_dev.h"
#include "sys/alt_alarm.h"
#include "sys/alt_warning.h"

#include "DE2_DRV11J_regs.h"

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */



/*
 *  Device structure definition. Each instance of the driver uses one of
 *  these structures to hold its associated state.
 */
typedef struct DRV11J_IO_DEVICE_s
{
    int intnum; /* interrupt this device uses*/

    unsigned char *sigin;
    unsigned char *sigout;
    unsigned short *datin;
    unsigned short *datout;

    unsigned int timeout;        /* a spin-loop timeout parameter    */
    int blocktime;            /* time read or write can block        */
    int error;            /* error register             */
    int byteCount;            /* byte count for I/O operations    */

    int sending;       /* TRUE while device is transmittin*/
    int receiving;     /* TRUE while device is receiving */
    unsigned short  rcv_data;
    unsigned short  send_data;

    /* counters */
    unsigned int rx_ints;

} DRV11J_IO_DEVICE;


typedef struct gpio_drv11j_buf_s
{
    unsigned short size;
    unsigned short data[GPIO_DRV11J_MAX_BUF_SIZE]; /* 256*/
    unsigned short crc;
} gpio_drv11j_buf;

/** GPIO Driver Hardware Instance Object
  @Summary
    Defines the object required for the maintenance of the hardware instance.
*/
typedef struct
{
    /* RX Byte Q */
    unsigned short                                      rxTail ;
    unsigned short                                      rxHead ;

    /* TX Byte Q : can only hold one command*/
    unsigned short                                      txTail;
    unsigned short                                      txHead ;

} GPIO_OBJECT ;

typedef struct
{
    unsigned char             u8Len;
    unsigned char             data[GPIO_DRV11J_MAX_BUF_SIZE];
}GPIO_Q;


/*
 * Device structure definition. Each instance of the driver uses one
 * of these structures to hold its associated state.
 */
typedef struct alt_parallel_port_dev_s{
    /// @brief device structure
    /// @sa Developing device drives for the HAL in Nios II Software Developer's Handbook
	alt_dev        dev;;
    /// @brief the base address of the device
    unsigned int base;
    DRV11J_IO_DEVICE drv11j;
}alt_pio_dev;

// system functions
// file-like operation functions



/*
 *   GPIO driver interface I/Os
 */
// direct operation functions
/**
 * @brief Open the parallel port device specified by <em> name </em>
 *
 * @param name -- the parallel port name. For example, if the parallel port name in SOPC Builder is "green_leds", then <em> name </em> should be "/dev/green_leds"
 *
 * @return The corresponding device structure, or NULL if the device is not found.
 **/
extern int alt_parallel_port_Open(alt_fd* fd, const char* name, int flags, int mode);
extern int alt_parallel_port_Close (alt_fd *fd);
extern int alt_parallel_port_Read( alt_fd* fd, unsigned char *buffer, const int bufLen);
extern int alt_parallel_port_Write(  alt_fd* fd, const unsigned char *buffer, const int bufLen );
extern int alt_parallel_port_Ioctl (alt_fd* fd, int req, void *data);
/*
 * Internal referenced routines
 */

extern int gpio_drv11j_Init( alt_pio_dev* pio_dev);

/*
 * Macros used by alt_sys_init
 */
#define DE2_DRV11J_SIGIN_INSTANCE(name, d)                      \
static alt_pio_dev d =                                          \
{                                                               \
  {                                                             \
    ALT_LLIST_ENTRY,                                            \
    name##_NAME,                                                \
    alt_parallel_port_Open, /* open */                                            \
    alt_parallel_port_Close, /* close */                        \
    alt_parallel_port_Read, /* read */                          \
    alt_parallel_port_Write, /* write */                        \
    NULL,														\
    NULL,														\
    alt_parallel_port_Ioctl, /* ioctl */                        \
   },                                                           \
    name##_BASE,                                                \
    {0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0 , 0}        \
} ;                                                             \





/*
 *  The initialisation function
 */
#define DE2_DRV11J_SIGIN_INIT(name, d)                       \
{                                                            \
	if (name##_IRQ != ALT_IRQ_NOT_CONNECTED)                 \
	 {                                                       \
		 /* make the device available to the system */       \
		gpio_drv11j_Init(&d);                               \
		/* make the device available to the system */        \
		alt_dev_reg (&d.dev);                                \
	 }                                                       \
}



#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif  /* _GPIO_DRV11J_H_ */
