/***************************************************************************/
/* example_pio_1.c
 * 
 * Build:  
 *  $COMMONCC -o example_pio1 example_pio1.c $VMELIBS
 *
 * Simple example for Programmed VME I/O in A32/D32, D16 and D08
 * with one VME channel.
 */ 
/***************************************************************************/

#include <stdio.h>
#include <sys/types.h>

#include "Vme.h"

#define VME_MAP_ADDRESS 0x10000000
#define VME_MAP_SIZE    1024*1024  /* 1 MB */ 
#define VME_MAP_AM      0x09       /* Extended VME address */

/***************************************************************************/
main (int argc, char *argv[])
/*---------------------------
*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
  u_long vme_address = VME_MAP_ADDRESS;
  int    cid, data;
  int    *vme_base;
/*.........................................................................*/

  /* Use a different VME base address if specified.
   */
  if ((argc==2)&&(sscanf(argv[1],"%x",&vme_address)!=1))
    {
      printf("Usage: %s <vme-base-address>\n",argv[0]);
      exit(1);
    }
  
  /* Open a VME channel for Programmed I/O.
   */
  cid = VmeOpenChannel("Example1","pio");
  if (cid < 0 ) 
    exit(1);
  
  /* Map VME address space.
   */
  vme_base = (int *)VmeMapAddress(cid,vme_address,VME_MAP_SIZE,VME_MAP_AM);
  if (vme_base == NULL)
    exit(1);
  
  /* Do not make direct VME access via pointer because it is not
   * supported on all systems ...
   */
#ifndef __alpha
  *vme_base = 0xdeadbeef;
#endif

  /* ... but use the following macros instead. This makes your code
   * more portable e.g. it will work on Alpha based VME boards as well.
   */

  Vme_D32WRITE( vme_base, &vme_base[0], 0xdeadbeef);

  Vme_D32READ ( vme_base, &vme_base[0], data);
  printf("Vme_D32READ at %08x = %8x\n", &vme_base[0], data); 

  Vme_D16READ ( vme_base, &vme_base[0], data);
  printf("Vme_D16READ at %08x = %4x\n", &vme_base[0], data&0xffff); 

  Vme_D08READ ( vme_base, &vme_base[0], data);
  printf("Vme_D08READ at %08x = %2x\n", &vme_base[0], data&0xff); 

  /* Close Vme channel. Do not forget to call this function before
   * you exit otherwise you might get some trouble later.
   */
  (void)VmeCloseChannel(cid);
}