#define ident "1A01" /* ** +--------------------------------------------------------------+ ** | Paul Scherrer Institute | ** | Computing Section | ** | | ** | This software may be used freely by non-profit organizations.| ** | It may be copied provided that the name of P.S.I. and of the | ** | author is included. Neither P.S.I. nor the author assume any | ** | responsibility for the use of this software outside of P.S.I.| ** +--------------------------------------------------------------+ ** ** Module Name . . . . . . . . : [...SINQHM]VMIO_UTILITY.C ** ** Author . . . . . . . . . . : D. Maden ** Date of creation . . . . . . : Mar 1997 ** ** Updates: ** 1A01 14-Mar-1997 DM Initial version. **--------------------------------------------------------------------------- ** VMIO_UTILITY.C is a set of routines for setting up and using a VMIO10. ** ** To compile this program for VxWorks on PSS123, use: ** ccvx vmio_utility.c ** where ccvx = ccppc -O0 \ -mcpu=603 \ -I${WIND_BASE}/target/h \ -fno-builtin \ -fno-for-scope \ -nostdinc \ -DCPU=PPC603 \ -D_GNU_TOOL \ -gdwarf -c -Wimplicit ** and, on the target, ** ** -> ld < vmio_utility.o **==================================================================== */ #include #include #include #include #include #include #include #include #include "vmio10_def.h" /* **==================== Global Definitions ===================================== */ #define NIL 0x00 #define DFLT_BASE_ADDR 0x1900 /* **==================== Global Variables ===================================== */ char *VmioBase; char Vme_dummy[256]; /* Dummy array - used only when VME access .. ** .. is disabled. */ char Null = 0x00; char Bit8 = 0x10; int My_errno; int Go_on; int Signal_has_happened; jmp_buf Trap_env; /* **============================================================================= ** Local routines. ** Forward references ... */ void vmio_byte_send (char bit8, char lobits); void vmio_enable (int ab_enbl, int bc_enbl); void vmio_pol_dir (int a_pol, int a_dir, int b_pol, int b_dir, int c_pol, int c_dir, int d_pol, int d_dir); void vmio_reset (); void vmio_send (char nbytes, char *buff); void vmio_transp_init (); /* **-----------------------------------------------------------------*/ void Signal_Handler (int sigint) { /* ============== */ Signal_has_happened = 1; printf ("Got into Signal_Handler\n"); longjmp (Trap_env, 1); } /* **-----------------------------------------------------------------*/ void vmio_byte_send (char bit8, char lobits) { /* ============== ** Send a byte (well, 9 bits really) via the VMIO10. */ char aux; do { /* Wait for Output Reg. empty */ VmioBase[VMIO_AB_CNTL] = 0X09; /* Select Port B status reg .. */ aux = VmioBase[VMIO_AB_CNTL]; /* .. and read it. */ } while ((aux & 0x08) == 0); /* Test its "empty" bit */ VmioBase[VMIO_PORT_C] = bit8; /* Send Bit-8 */ VmioBase[VMIO_PORT_B] = lobits; /* Output the other bits */ } /* **-----------------------------------------------------------------*/ void vmio_enable (int ab_enbl, int bc_enbl) { /* =========== ** output/input enable for IC6 ,IC7 */ VmioBase[VMIO_AB_CNTL] = Z8536_MCCR; /* Select Master Config Control Reg */ VmioBase[VMIO_AB_CNTL] = ab_enbl; VmioBase[VMIO_CD_CNTL] = Z8536_MCCR; VmioBase[VMIO_CD_CNTL] = bc_enbl; } /* **-----------------------------------------------------------------*/ void vmio_pol_dir ( /* ============ Set Polarity and Direction of VMIO10 Module ** A, B, C and D registers. ** Polarity bit = 0 for non-inverting. ** Direction bit = 0 for output. */ int a_pol, int a_dir, int b_pol, int b_dir, int c_pol, int c_dir, int d_pol, int d_dir) { VmioBase[VMIO_AB_CNTL] = Z8536_DPPR_A; /* Port A %10'0010, Data Path Pol */ VmioBase[VMIO_AB_CNTL] = a_pol; VmioBase[VMIO_AB_CNTL] = Z8536_DDR_A; /* Port A %10'0011, Data Direction */ VmioBase[VMIO_AB_CNTL] = a_dir; VmioBase[VMIO_AB_CNTL] = Z8536_DPPR_B; /* Port B %10'1010, Data Path Pol */ VmioBase[VMIO_AB_CNTL] = b_pol; VmioBase[VMIO_AB_CNTL] = Z8536_DDR_B; /* Port B %10'1011, Data Direction */ VmioBase[VMIO_AB_CNTL] = b_dir; VmioBase[VMIO_CD_CNTL] = Z8536_DPPR_A; /* Port C %10'0010, Data Path Pol */ VmioBase[VMIO_CD_CNTL] = c_pol; VmioBase[VMIO_CD_CNTL] = Z8536_DDR_A; /* Port C %10'0011, Data Direction */ VmioBase[VMIO_CD_CNTL] = c_dir; VmioBase[VMIO_CD_CNTL] = Z8536_DPPR_B; /* Port D %10'1010, Data Path Pol */ VmioBase[VMIO_CD_CNTL] = d_pol; VmioBase[VMIO_CD_CNTL] = Z8536_DDR_B; /* Port D %10'0011, Data Direction */ VmioBase[VMIO_CD_CNTL] = d_dir; } /* **-----------------------------------------------------------------*/ void vmio_reset () { /* ========== ** Software reset for VMIO10 module */ char aux; /* ** Start by forcing the state machine into State 0 */ aux = VmioBase[VMIO_AB_CNTL]; /* Read Cntrl to ensure not State 1 */ VmioBase[VMIO_AB_CNTL] = NIL; /* Write zero to Cntrl to ensure not in .. ** .. "Reset State" */ aux = VmioBase[VMIO_AB_CNTL]; /* Read Cntrl to ensure State 0 */ VmioBase[VMIO_AB_CNTL] = Z8536_MICR; /* Select the Master Int Ctrl Reg */ VmioBase[VMIO_AB_CNTL] = 0x01; /* Set the reset bit */ VmioBase[VMIO_AB_CNTL] = NIL; /* Then clear it to complete reset */ /* ** Repeat for the other Z8536-CIO */ aux = VmioBase[VMIO_CD_CNTL]; VmioBase[VMIO_CD_CNTL] = NIL; aux = VmioBase[VMIO_CD_CNTL]; VmioBase[VMIO_CD_CNTL] = Z8536_MICR; VmioBase[VMIO_CD_CNTL] = 0x01; VmioBase[VMIO_CD_CNTL] = NIL; } /* **-----------------------------------------------------------------*/ void vmio_send ( /* ========= Send bytes to the LWL. */ char nbytes, char *buff) { /* ** The bytes are buff[0] to buff[nbytes-1]. buff[0] gives the ** headerbit for buff[1]. The remainder are sent with the 9th ** bit clear. */ int i; char aux; /* ** ---------- loop sending the bytes --------------- */ VmioBase[VMIO_PORT_C] = 0; /* Mode = 0 */ if (nbytes < 2) return; vmio_byte_send (buff[0], buff[1]); /* 2 bytes define the first "LWL-byte" */ if (nbytes < 3) return; for (i = 2; i < nbytes; i++) { /* The remaining bytes have Bit-8 = 0 */ vmio_byte_send (NIL, buff[i]); } } /* **-----------------------------------------------------------------*/ void vmio_transp_init () { /* ================ ** Initialise VMIO10 ready for transparent ** transmission of data. */ /* ** ---------- initialize i/o --------------- */ VmioBase[VMIO_AB_CNTL] = 0x28; /* Port B output port-Mode Spec. Reg */ VmioBase[VMIO_AB_CNTL] = 0x80; VmioBase[VMIO_AB_CNTL] = 0x29; /* Port B handshake interlock */ VmioBase[VMIO_AB_CNTL] = 0x00; } /*============================================================================== ** Main line program ** ------------------ **============================================================================*/ int vmio_utility (char *base_addr) { /*============================================================================*/ STATUS status; int i; char aux; void (* sig_status) (int); /*============================================================================ ** Perform the initialisation of global variables ... */ /*============================================================================ ** Get the VME base address of the Test Generator Module. ** If the argument "base_addr" is zero, use DFLT_BASE_ADDR. */ if (base_addr == NULL) base_addr = (char *) DFLT_BASE_ADDR; #ifdef _NO_VME printf ("VMIO_UTILITY: Warning, VME access disabled.\n"); VmioBase = &Vme_dummy[0]; #else status = sysBusToLocalAdrs (VME_AM_USR_SHORT_IO, base_addr, &VmioBase); if (status != OK) { printf ("Error status from sysBusToLocalAdrs\n"); return ERROR; } #endif /* ** See if the module is present */ Signal_has_happened = 0; sig_status = signal (SIGBUS, Signal_Handler); /* Catch machine checks */ if (sig_status == SIG_ERR) { printf (" Problem setting up a signal handler!\n"); return ERROR; } i = setjmp (Trap_env); if (i == 0) aux = VmioBase[VMIO_AB_CNTL]; if (Signal_has_happened != 0) { printf ("VMIO10 Module not present -- exiting!\n"); return ERROR; } /* ** Reset the VMIO10 Module. */ vmio_reset (); /* ** Set Ports A, B, C and D to non-inverting and output */ vmio_pol_dir (NIL, NIL, /* Port A */ NIL, NIL, /* Port B */ NIL, NIL, /* Port C */ NIL, NIL); /* Port D */ /* ** Enable Ports A, B, C and D. */ vmio_enable (0x84, 0x84); Go_on = 0; for (;;) { for (i=0; i<1000; i++) {} if (Go_on != 0) break; VmioBase[VMIO_PORT_A] = 0xff; VmioBase[VMIO_PORT_A] = 0x00; VmioBase[VMIO_PORT_A] = 0xff; VmioBase[VMIO_PORT_A] = 0x00; VmioBase[VMIO_PORT_A] = 0xff; VmioBase[VMIO_PORT_A] = 0x00; } printf ("Vmio_Utility exiting\n"); return OK; } /*===================================== End of VMIO_UTILITY.C =============*/