/*************************************************** * scaler_write_preset() ****************************************************/ STATIC long scaler_write_preset(scalerRecord *psr, int signal, long val) { devScalerPvt *dpvt = psr->dpvt; int card = dpvt->card; volatile char *addr= scaler_state[card]->localAddr; short mask; int offset= PRESET_0_OFFSET+signal*4; Debug(5,"scaler_write_preset: card %d\n", card); Debug(5,"scaler_write_preset: signal %d\n", signal); Debug(5,"scaler_write_preset: val = %d\n", (int)val); if ((card+1) > scaler_total_cards) return(ERROR); if (!scaler_state[card]->card_exists) return(ERROR); if ((signal+1) > MAX_SCALER_CHANNELS) return(ERROR); /* write preset; save a copy in scaler_state */ writeReg32(addr,offset,val-1); scaler_state[card]->preset[signal] = val-1; /* make the preset scaler count down */ mask = readReg16(addr,DIRECTION_OFFSET); mask |= 1<<signal; Debug(5,"scaler_write_preset: up/down mask = 0x%x\n", mask); writeReg16(addr,DIRECTION_OFFSET,mask); /* enable IRQ from preset channel */ mask = readReg16(addr,IRQ_MASK_OFFSET); mask |= 1<<signal; Debug(5,"scaler_write_preset: IRQ mask = 0x%x\n", mask); writeReg16(addr,IRQ_MASK_OFFSET,mask); return(0); }
/*************************************************** * scaler_read() * return pointer to array of scaler values (on the card) ****************************************************/ STATIC long scaler_read(scalerRecord *psr, long *val) { devScalerPvt *dpvt = psr->dpvt; int card = dpvt->card; long preset; unsigned long rawval; volatile char *addr= scaler_state[card]->localAddr; int i, offset; unsigned short mask; Debug(8,"scaler_read: card %d\n", card); if ((card+1) > scaler_total_cards) return(ERROR); if (!scaler_state[card]->card_exists) return(ERROR); mask = readReg16(addr,DIRECTION_OFFSET); Debug(5,"scaler_read: readback of up/down mask: 0x%x\n", mask); mask = readReg16(addr,IRQ_MASK_OFFSET); Debug(5,"scaler_read: readback of IRQ mask: 0x%x\n", mask); for (i=0, offset=DATA_0_OFFSET; i < scaler_state[card]->num_channels; i++, offset+=4) { preset = scaler_state[card]->preset[i]; rawval = readReg32(addr,offset); val[i] = (mask & (1<<i)) ? preset-rawval:rawval; if (i <= (devScalerDebug-19)) { logMsg("scaler_read: channel %d\n", i); logMsg("scaler_read: ...(dir i = %s)\n", (mask & (1<<i)) ? "DN":"UP"); logMsg("scaler_read: ...(preset i = %d)\n", (unsigned int)preset); logMsg("scaler_read: ...(data i = %d)\n",rawval); logMsg("scaler_read: ...(chan i = %d)\n\n", (unsigned int)val[i]); } } return(0); }
/************************************************** * scalerISR() ***************************************************/ STATIC void scalerISR(int card) { volatile char *addr; uint16 value; Debug(5, "%s", "scalerISR: entry\n"); if ((card+1) > scaler_total_cards) return; addr = scaler_state[card]->localAddr; /* disable interrupts during processing */ value = readReg16(addr, IRQ_LEVEL_ENABLE_OFFSET) & 0x7f; writeReg16(addr, IRQ_LEVEL_ENABLE_OFFSET, value); /* clear interrupt */ writeReg16(addr,IRQ_RESET_OFFSET, 0); /* tell record support the hardware is done counting */ scaler_state[card]->done = 1; /* get the record processed */ callbackRequest(scaler_state[card]->pcallback); /* enable interrupts */ value = readReg16(addr, IRQ_LEVEL_ENABLE_OFFSET) | 0x80; writeReg16(addr, IRQ_LEVEL_ENABLE_OFFSET, value); return; }
/*************************************************** * scalerVS_read() * return pointer to array of scaler values (on the card) ****************************************************/ STATIC long scalerVS_read(scalerRecord *psr, long *val) { devScalerPvt *dpvt = psr->dpvt; int card = dpvt->card; volatile char *addr; int i, offset; Debug(8,"scalerVS_read: card %d\n", card); if (card >= scalerVS_total_cards) return(ERROR); addr = scalerVS_state[card]->localAddr; /* any write clocks all transfer registers */ writeReg16(addr,CLOCK_XFER_REG_OFFSET,1); for (i=0, offset=READ_XFER_REG_OFFSET; i < scalerVS_state[card]->num_channels; i++, offset+=4) { val[i] = readReg32(addr,offset); if (i==0) { Debug2(11,"scalerVS_read: ...(chan %d = %ld)\n", i, val[i]); } else { Debug2(20,"scalerVS_read: ...(chan %d = %ld)\n", i, val[i]); } } Debug2(10,"scalerVS_read: status=0x%x; irq vector=0x%x\n", readReg16(scalerVS_state[card]->localAddr,STATUS_OFFSET), readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET)&0xff); return(0); }
/************************************************** * scalerISRSetup() ***************************************************/ STATIC int scalerISRSetup(int card) { long status; volatile char *addr; int intLevel; Debug(5, "scalerISRSetup: Entry, card #%d\n", card); if ((card+1) > scaler_total_cards) return(ERROR); addr = scaler_state[card]->localAddr; status = devConnectInterrupt(intVME, vsc_InterruptVector + card, (void *) &scalerISR, (void *) card); if (!RTN_SUCCESS(status)) { errPrintf(status, __FILE__, __LINE__, "Can't connect to vector %ld\n", vsc_InterruptVector + card); return (ERROR); } /* get interrupt level from hardware, and enable that level in EPICS */ intLevel = readReg16(addr,IRQ_LEVEL_ENABLE_OFFSET) & 5 /*3*/; Debug(5, "scalerISRSetup: Interrupt level %d\n", intLevel); status = devEnableInterruptLevel(intVME, intLevel); if (!RTN_SUCCESS(status)) { errPrintf(status, __FILE__, __LINE__, "Can't enable enterrupt level %d\n", intLevel); return (ERROR); } /* Write interrupt vector to hardware */ writeReg16(addr,IRQ_VECTOR_OFFSET,(unsigned short) (vsc_InterruptVector + card)); Debug(5, "scalerISRSetup: Exit, card #%d\n", card); return (OK); }
/*************************************************** * scaler_reset() ****************************************************/ STATIC long scaler_reset(scalerRecord *psr) { volatile char *addr; int i; uint16 value; devScalerPvt *dpvt = psr->dpvt; int card = dpvt->card; Debug(5,"scaler_reset: card %d\n", card); if ((card+1) > scaler_total_cards) return(ERROR); if (!scaler_state[card]->card_exists) return(ERROR); addr = scaler_state[card]->localAddr; /* disable interrupt */ value = readReg16(addr, IRQ_LEVEL_ENABLE_OFFSET) & 0x7f; writeReg16(addr, IRQ_LEVEL_ENABLE_OFFSET, value); /* reset board */ writeReg16(addr,RESET_OFFSET, 0); /* zero local copy of scaler presets */ for (i=0; i<MAX_SCALER_CHANNELS; i++) { scaler_state[card]->preset[i] = 0; } /* clear hardware-done flag */ scaler_state[card]->done = 0; return(0); }
/************************************************** * scaler_report() ***************************************************/ STATIC long scaler_report(int level) { int card; volatile char *addr; uint16 term=0; if ((vsc_num_cards <=0) || (scaler_state[0]->card_exists == 0)) { printf(" No Joerger VSCxx scaler cards found.\n"); } else { for (card = 0; card < vsc_num_cards; card++) { if (scaler_state[card] && scaler_state[card]->card_exists) { addr = scaler_state[card]->localAddr; term = readReg16(addr,MODULE_TYPE_OFFSET); printf(" Joerger VSC%-2d card %d @ %p, id: %d %s inputs:%s\n", scaler_state[card]->num_channels, card, scaler_state[card]->localAddr, (unsigned int) scaler_state[card]->ident, scaler_state[card]->card_in_use ? "(in use)": "(NOT in use)", (term==16) ? "TTL" : (term==17) ? "NIM" : (term==18) ? "ECL" : "?"); } } } return (0); }
// Return true if ok. boolean readVoltage(uint16* raw_register_value, uint16* voltage_mv) { if (!readReg16(regs16::kVoltage, raw_register_value)) { return false; } // NOTE: using a top value of 0x10000 instead of 0xffff as specified in the datasheet. // The affect on the accuracy is insignificant. Adding the 0x8000 to round to the closest // mv. *voltage_mv = ((((uint32)23600) * (*raw_register_value)) + 0x8000) >> 16; return true; }
/* debugging function */ void VSCscaler_debug(int card, int numReads, int waitLoops) { volatile char *addr = scaler_state[card]->localAddr; int i, j, offset; if (vsc_num_cards == 0) { printf("VSCscaler_debug: No Joerger VSC cards\n"); return; } printf("VSCscaler_debug: card %d %s\n", card, scaler_state[card]->card_exists ? "exists" : "not found"); if (!scaler_state[card]->card_exists) return; for (i=0; i<numReads; i++) { printf("VSCscaler_debug: ctrl reg = 0x%x\n", readReg16(addr,CTRL_OFFSET) &0xf); for (j=0; j<waitLoops; j++); } for (i=0; i<numReads; i++) { printf("VSCscaler_debug: dir reg = 0x%x\n",readReg16(addr,DIRECTION_OFFSET) ); for (j=0; j<waitLoops; j++); } for (i=0; i<numReads; i++) { printf("VSCscaler_debug: irq vector = 0x%x\n",readReg16(addr,STATUS_ID_OFFSET) &0xff); for (j=0; j<waitLoops; j++); } for (i=0; i<numReads; i++) { printf("VSCscaler_debug: irq level/enable = 0x%x\n",readReg16(addr,IRQ_LEVEL_ENABLE_OFFSET) &0xff); for (j=0; j<waitLoops; j++); } for (i=0; i<numReads; i++) { printf("VSCscaler_debug: irq mask reg = 0x%x\n", readReg16(addr,IRQ_MASK_OFFSET)); for (j=0; j<waitLoops; j++); } for (i=0; i<numReads; i++) { printf("VSCscaler_debug: rev. ser# reg = 0x%x\n", readReg16(addr,REV_SERIAL_NO_OFFSET)); for (j=0; j<waitLoops; j++); } for (i=0; i<numReads; i++) { printf("VSCscaler_debug: module type = 0x%x\n",readReg16(addr,MODULE_TYPE_OFFSET) &0xff); for (j=0; j<waitLoops; j++); } for (i=0; i<numReads; i++) { printf("VSCscaler_debug: manuf. ID = 0x%x\n",readReg16(addr,MANUFACTURER_ID_OFFSET) &0xff); for (j=0; j<waitLoops; j++); } offset = DATA_0_OFFSET; for (i=0; i<2; i++, offset+=4 ) { for (j=0; j<numReads; j++) { printf(" VSCscaler_debug: channel %d counts = %d\n", i,readReg32(addr,offset) ); } } /* Note reading from PRESET_0_OFFSET reads and clears data at DATA_0_OFFSET */ }
/************************************************** * scalerEndOfGateISRSetup() ***************************************************/ STATIC int scalerEndOfGateISRSetup(int card) { long status; volatile char *addr; volatile uint16 u16; Debug(5, "scalerEndOfGateISRSetup: Entry, card #%d\n", card); if (card >= scalerVS_total_cards) return(ERROR); addr = scalerVS_state[card]->localAddr; status = devConnectInterruptVME(vs_InterruptVector + card, (void *) &scalerEndOfGateISR, (void *)card); if (!RTN_SUCCESS(status)) { errPrintf(status, __FILE__, __LINE__, "Can't connect to vector %d\n", vs_InterruptVector + card); return (ERROR); } /* write interrupt level to hardware, and tell EPICS to enable that level */ u16 = readReg16(addr,IRQ_SETUP_OFFSET) & 0x0ff; /* OR in level for end-of-gate interrupt */ writeReg16(addr,IRQ_SETUP_OFFSET, u16 | (vs_InterruptLevel << 8)); status = devEnableInterruptLevelVME(vs_InterruptLevel); if (!RTN_SUCCESS(status)) { errPrintf(status, __FILE__, __LINE__, "Can't enable enterrupt level %d\n", vs_InterruptLevel); return (ERROR); } Debug(5, "scalerEndOfGateISRSetup: Wrote interrupt level, %d, to hardware\n", vs_InterruptLevel); /* Write interrupt vector to hardware */ writeReg16(addr,IRQ_3_GATE_VECTOR_OFFSET, (uint16)(vs_InterruptVector + card)); Debug(5, "scalerEndOfGateISRSetup: Wrote interrupt vector, %d, to hardware\n", vs_InterruptVector + card); Debug(5, "scalerEndOfGateISRSetup: Read interrupt vector, %d, from hardware\n", readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET) & 0x0ff); Debug(5, "scalerEndOfGateISRSetup: Exit, card #%d\n", card); return (OK); }
/*************************************************** * scaler_arm() * Make scaler ready to count. If ARM output is connected * to ARM input, and GATE input permits, the scaler will * actually start counting. ****************************************************/ STATIC long scaler_arm(scalerRecord *psr, int val) { devScalerPvt *dpvt = psr->dpvt; int card = dpvt->card; volatile char *addr=scaler_state[card]->localAddr; short ctrl_data; uint16 value; Debug(5,"scaler_arm: card %d\n", card); Debug(5,"scaler_arm: val = %d\n", val); if ((card+1) > scaler_total_cards) return(ERROR); if (!scaler_state[card]->card_exists) return(ERROR); /* disable interrupt */ value = readReg16(addr,IRQ_LEVEL_ENABLE_OFFSET) & 0x7f; writeReg16(addr,IRQ_LEVEL_ENABLE_OFFSET,value); if (val) { /* write the interrupt vector to the board */ writeReg16(addr,IRQ_VECTOR_OFFSET,(unsigned short)(vsc_InterruptVector+card)); /* enable interrupt-when-done */ value = readReg16(addr,IRQ_LEVEL_ENABLE_OFFSET) | 0x80; writeReg16(addr,IRQ_LEVEL_ENABLE_OFFSET,value); } /* clear hardware-done flag */ scaler_state[card]->done = 0; /* arm scaler */ ctrl_data = readReg16(addr,CTRL_OFFSET); if (val) ctrl_data |= 1; else ctrl_data &= 0x0E; writeReg16(addr,CTRL_OFFSET,ctrl_data); Debug(5,"scaler_arm: ctrl reg => 0x%x\n",readReg16(addr,CTRL_OFFSET) & 0xf); return(0); }
/*************************************************** * scaler_read() * return pointer to array of scaler values (on the card) ****************************************************/ STATIC long scaler_read(scalerRecord *psr, long *val) { devScalerPvt *dpvt = psr->dpvt; int card = dpvt->card; long preset; volatile char *addr= scaler_state[card]->localAddr; int i, offset; unsigned short mask; Debug(8,"scaler_read: card %d\n", card); if ((card+1) > scaler_total_cards) return(ERROR); if (!scaler_state[card]->card_exists) return(ERROR); mask = readReg16(scaler_state[card]->localAddr,DIRECTION_OFFSET); for (i=0, offset=DATA_0_OFFSET; i < scaler_state[card]->num_channels; i++, offset+=4) { preset = scaler_state[card]->preset[i]; val[i] = (mask & (1<<i)) ? preset-readReg32(addr,offset):readReg32(addr,offset); Debug(20,"scaler_read: ...(dir i = %s)\n", (mask & (1<<i)) ? "DN":"UP"); Debug(20,"scaler_read: ...(preset i = 0x%x)\n", (unsigned int)preset); Debug(20,"scaler_read: ...(data i = 0x%x)\n",readReg32(addr,offset)); Debug(10,"scaler_read: ...(chan i = 0x%x)\n\n", (unsigned int)val[i]); } return(0); }
/* debugging function */ void scalerVS_show(int card, int level) { volatile char *addr; int i, num_channels, offset, saveDebug; char module_type[16]; printf("scalerVS_show: software version: %f\n", VERSION); printf("scalerVS_show: %ld Joerger VS cards in use.\n", vs_num_cards); if ((vs_num_cards == 0) || (card >= vs_num_cards)) return; addr = scalerVS_state[card]->localAddr; saveDebug = devScaler_VSDebug; devScaler_VSDebug = 0; printf("scalerVS_show: card %d\n", card); printf("scalerVS_show: local address %p\n", addr); printf("scalerVS_show: control reg = 0x%x\n", readReg16(addr,CTRL_OFFSET) & 0x3); printf("scalerVS_show: status reg = 0x%x\n", readReg16(addr,STATUS_OFFSET) & 0x1ff); printf("scalerVS_show: irq level/enable = 0x%x\n", readReg16(addr,IRQ_SETUP_OFFSET) & 0xfff); printf("scalerVS_show: irq 3 (end-of-gate) interrupt vector = %d\n", readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET) & 0xff); i = (readReg16(addr,ID_OFFSET) & 0xfc00) >> 10; if ((i >= 16) && (i <= 29)) { strncpy(module_type, VS_module_types[i-16].type, 15); num_channels = VS_module_types[i-16].num_channels; } else { sprintf(module_type, "unknown(%d)", i); num_channels = 0; } printf("scalerVS_show: module type = %d ('%s'), %d channels, serial # %d\n", i, module_type, num_channels, readReg16(addr,ID_OFFSET) & 0x3ff); num_channels = level ? scalerVS_state[card]->num_channels : 1; for (i=0, offset=READ_XFER_REG_OFFSET; i<num_channels; i++, offset+=4) { printf(" scalerVS_show: channel %d xfer-reg counts = %u\n", i, readReg32(addr,offset)); } printf("scalerVS_show: scalerVS_state[card]->done = %d\n", scalerVS_state[card]->done); devScaler_VSDebug = saveDebug; return; }
/* debugging function */ void VSCscaler_show(int card) { volatile char *addr = scaler_state[card]->localAddr; int i, offset; if (vsc_num_cards == 0) { printf("VSCscaler_show: No Joerger VSC cards\n"); return; } printf("VSCscaler_show: card %d %s\n", card, scaler_state[card]->card_exists ? "exists" : "not found"); if (!scaler_state[card]->card_exists) return; printf("VSCscaler_show: ctrl reg = 0x%x\n", readReg16(addr,CTRL_OFFSET) &0xf); printf("VSCscaler_show: dir reg = 0x%x\n",readReg16(addr,DIRECTION_OFFSET) ); printf("VSCscaler_show: irq vector = 0x%x\n",readReg16(addr,STATUS_ID_OFFSET) &0xff); printf("VSCscaler_show: irq level/enable = 0x%x\n",readReg16(addr,IRQ_LEVEL_ENABLE_OFFSET) &0xff); printf("VSCscaler_show: irq mask reg = 0x%x\n", readReg16(addr,IRQ_MASK_OFFSET)); printf("VSCscaler_show: module type = 0x%x\n",readReg16(addr,MODULE_TYPE_OFFSET) &0xff); offset = DATA_0_OFFSET; for (i=0; i<scaler_state[card]->num_channels; i++, offset+=4 ) { printf(" VSCscaler_show: channel %d counts = %d\n", i,readReg32(addr,offset) ); } printf("VSCscaler_show: scaler_state[card]->done = %d\n", scaler_state[card]->done); }
/*************************************************** * scalerVS_arm() * Make scaler ready to count. If ARM output is connected * to ARM input, and GATE permits, the scaler will * actually start counting. ****************************************************/ STATIC long scalerVS_arm(scalerRecord *psr, int val) { devScalerPvt *dpvt = psr->dpvt; int card = dpvt->card; volatile char *addr; volatile uint16 u16; int i, j, retry, read_again, numBad, numGood; Debug2(1, "scalerVS_arm: card %d, val %d\n", card, val); if (card >= scalerVS_total_cards) return(ERROR); addr = scalerVS_state[card]->localAddr; callbackGetUser(psr, scalerVS_state[card]->pcallback); /* disable end-of-gate interrupt */ u16 = readReg16(addr,IRQ_SETUP_OFFSET); writeReg16(addr,IRQ_SETUP_OFFSET, u16 & 0x07ff); if (val) { /*** start counting ***/ /* reset counters, overflows, and overflow-IRQ source */ writeReg16(addr,RESET_ALL_COUNTERS_OFFSET, (uint16)1); /* clear other IRQ's */ writeReg16(addr,CLEAR_INTERRUPT_2_3_OFFSET, (uint16)3); /** Set up and enable interrupts **/ /* Write interrupt vector to hardware */ writeReg16(addr,IRQ_3_GATE_VECTOR_OFFSET, (uint16)(vs_InterruptVector + card)); Debug(10,"scalerVS_arm: irq vector=%d\n", (int)readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET) & 0x00ff); /* set end-of-gate interrupt level, and enable the interrupt */ u16 = readReg16(addr, IRQ_SETUP_OFFSET); u16 = (u16 & 0x0ff) | (vs_InterruptLevel << 8) | 0x800; writeReg16(addr, IRQ_SETUP_OFFSET, u16); /* * How do I make sure the internal-gate counter is zero, and that it * won't start counting as soon as ARM goes TRUE? */ /* clear hardware-done flag */ scalerVS_state[card]->done = 0; /* enable all channels */ writeReg16(addr, COUNT_ENABLE_OFFSET, 1); /* any write enables */ /* arm scaler */ writeReg16(addr, ARM_OFFSET, 1); /* any write sets ARM */ /* Make sure trigger mode is set for internal gate. */ /* (This was already done in write_preset(). It's ok to do it again.) */ u16 = readReg16(addr, CLOCK_TRIG_MODE_OFFSET); writeReg16(addr, CLOCK_TRIG_MODE_OFFSET, u16 | 0x0010); /* trigger gate */ if (devScaler_VS_check_trig) { for (i=0, retry=1; retry && i<devScaler_VS_trig_retries; i++) { writeReg16(addr, TRIG_GATE_OFFSET, 1); /* any write triggers gate */ /* * Check status register bit 9 to make sure internal gate is open. * Repeat reading until we get the same value devScaler_VS_trig_reads * times in a row. */ for (read_again = 1; read_again; ) { for (j=0, numBad=numGood=0; j<devScaler_VS_trig_reads; j++) { u16 = readReg16(addr, STATUS_OFFSET); if (u16 & 0x0200) numGood++; else numBad++; } if (numBad == devScaler_VS_trig_reads) { /* we believe the gate did NOT get triggered */ retry = 1; read_again = 0; } else if (numGood == devScaler_VS_trig_reads) { /* we believe the gate got triggered */ retry = 0; read_again = 0; } } } if (retry) { printf("scalerVS_arm: %d trigger attempts apparently failed\n", i); } else if (i >= devScaler_VS_trig_retry_report) { Debug(1,"scalerVS_arm: trigger succeeded after %d retries.\n", i); } } else { writeReg16(addr, TRIG_GATE_OFFSET, 1); /* any write triggers gate */ } Debug2(5,"scalerVS_arm: gate open; SR=0x%x; irq vector=%d\n", readReg16(addr, STATUS_OFFSET), (int)readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET) & 0x00ff); } else { /*** stop counting ***/ /* disarm scaler */ writeReg16(addr, DISARM_OFFSET, 1); /* any write resets ARM */ /* * Stop counter (change trigger mode from internal gate to external gate * (external gate should be 1?) */ u16 = readReg16(addr, CLOCK_TRIG_MODE_OFFSET); writeReg16(addr, CLOCK_TRIG_MODE_OFFSET, u16 & 0x000f); /* set hardware-done flag */ scalerVS_state[card]->done = 1; } return(0); }
/*************************************************** * initialize all software and hardware * scaler_init() ****************************************************/ STATIC long scaler_init(int after) { volatile char *localAddr; unsigned long status; void *baseAddr; int card, i; uint32 probeValue = 0; Debug(2,"scaler_init(): entry, after = %d\n", after); if (after || (vsc_num_cards == 0)) return(0); /* allocate scaler_state structures, array of pointers */ if (scaler_state == NULL) { scaler_state = (struct scaler_state **) calloc(1, vsc_num_cards * sizeof(struct scaler_state *)); scaler_total_cards=0; for (card=0; card<vsc_num_cards; card++) { scaler_state[card] = (struct scaler_state *) calloc(1, sizeof(struct scaler_state)); } } /* Check out the hardware. */ for (card=0; card<vsc_num_cards; card++) { baseAddr = (void *)(vsc_addrs + card*CARD_ADDRESS_SPACE); /* Can we reserve the required block of VME address space? */ status = devRegisterAddress(__FILE__, atVMEA32, (size_t)baseAddr, CARD_ADDRESS_SPACE, (volatile void **)&localAddr); if (!RTN_SUCCESS(status)) { errPrintf(status, __FILE__, __LINE__, "Can't register 0x%x-byte block at address %p\n", CARD_ADDRESS_SPACE, baseAddr); return (ERROR); } if (devReadProbe(4,(volatile void *)(localAddr+DATA_0_OFFSET),(void*)&probeValue)) { printf("no VSC card at %p\n",localAddr); return(0); } /* Declare victory. */ Debug(2,"scaler_init: we own 256 bytes starting at %p\n",localAddr); scaler_state[card]->localAddr = localAddr; scaler_total_cards++; /* reset this card */ writeReg16(localAddr,RESET_OFFSET,0); /* get this card's identification */ scaler_state[card]->ident = readReg16(localAddr,REV_SERIAL_NO_OFFSET); Debug(3,"scaler_init: Serial # = %d\n", scaler_state[card]->ident); scaler_state[card]->card_exists = 1; /* get this card's type (8 or 16 channels?) */ Debug(2,"scaler_init:Base Address=0x%8.8x\n",(int)baseAddr); Debug(2,"scaler_init:Local Address=0x%8.8x\n",(int)localAddr); scaler_state[card]->num_channels = readReg16(localAddr,MODULE_TYPE_OFFSET) & 0x18; Debug(3,"scaler_init: nchan = %d\n", scaler_state[card]->num_channels); if (scaler_state[card]->num_channels < 8) { scaler_state[card]->card_exists = 0; continue; } for (i=0; i<MAX_SCALER_CHANNELS; i++) { scaler_state[card]->preset[i] = 0; } } Debug(3,"scaler_init: Total cards = %d\n\n",scaler_total_cards); #ifdef vxWorks if (epicsAtExit(scaler_shutdown, 0) < 0) epicsPrintf ("scaler_init: epicsAtExit() failed\n"); #endif Debug(3, "%s", "scaler_init: scalers initialized\n"); return(0); }
void scalerVS_regShow(int card, int level) { volatile char *addr; volatile uint16 stat, ctrl, a32_1, a32_0, irq, clkt, gate, ref; volatile unsigned char irq1, irq2, irq3; int saveDebug; if ((vs_num_cards == 0) || (card >= vs_num_cards)) { printf("scalerVS_regShow: no such card.\n"); return; } addr = scalerVS_state[card]->localAddr; saveDebug = devScaler_VSDebug; devScaler_VSDebug = 0; stat = readReg16(addr,0x400); ctrl = readReg16(addr,0x402); a32_1 = readReg16(addr,0x404); a32_0 = readReg16(addr,0x406); irq1 = readReg16(addr,0x408)&0xff; irq2 = readReg16(addr,0x40A)&0xff; irq3 = readReg16(addr,0x40C)&0xff; irq = readReg16(addr,0x40E); clkt = readReg16(addr,0x410); gate = readReg16(addr,0x412); ref = readReg16(addr,0x414); if (level>1) printf("scalerVS_regShow: 0400 0402 0404 0406 0408 040A 040C 040E 0410 0412 0414\n"); if (level>0) printf("scalerVS_regShow: STAT CTRL A321 A320 IRQ1 IRQ2 IRQ3 IRQ* CLKT GATE REF\n"); printf("scalerVS_regShow: %04hX %04hX %04hX %04hX %04hX %04hX %04hX %04hX %04hX %04hX %04hX\n", stat, ctrl, a32_1, a32_0, (uint16)irq1, (uint16)irq2, (uint16)irq3, irq, clkt, gate, ref); if (level>2) { printf(" STAT CTRL IRQ* CLKT REF\n"); printf("15 - - - - -\n"); printf("14 - - - - -\n"); printf("13 - - - - -\n"); printf("12 FPArmOut - - - -\n"); printf("\n"); printf("11 FPArmIn - GateEnbl - -\n"); printf("10 FPGateIn - Gate_2 - -\n"); printf("09 ProgGate - Gate_1 - -\n"); printf("08 FPReset - Gate_0 - -\n"); printf("\n"); printf("07 Gate - FPXferEnbl - -\n"); printf("06 FPXfer - FPXfer_2 - -\n"); printf("05 Ovflo - FPXfer_1 - -\n"); printf("04 GateSrc - IFPXfer_0 TrigMode -\n"); printf("\n"); printf("03 FPXferSrc - OfloEnbl Freq_3 EnblRefClk\n"); printf("02 OvfloSrc - OfloLev_2 Freq_2 Freq_2\n"); printf("01 GblCntEnblFF EnblGblResOnFPXClk OfloLev_1 Freq_1 Freq_1\n"); printf("00 GblCntEnbl EnblGblResOnVMEXClk OfloLev_0 Freq_0 Freq_0\n"); } devScaler_VSDebug = saveDebug; }
//============================================================================= bool SdioCard::begin() { uint32_t kHzSdClk; uint32_t arg; m_initDone = false; m_errorCode = SD_CARD_ERROR_NONE; m_highCapacity = false; m_version2 = false; // initialize controller. initSDHC(); if (!cardCommand(CMD0_XFERTYP, 0)) { return sdError(SD_CARD_ERROR_CMD0); } // Try several times for case of reset delay. for (uint32_t i = 0; i < CMD8_RETRIES; i++) { if (cardCommand(CMD8_XFERTYP, 0X1AA)) { if (SDHC_CMDRSP0 != 0X1AA) { return sdError(SD_CARD_ERROR_CMD8); } m_version2 = true; break; } } arg = m_version2 ? 0X40300000 : 0x00300000; uint32_t m = micros(); do { if (!cardAcmd(0, ACMD41_XFERTYP, arg) || ((micros() - m) > BUSY_TIMEOUT_MICROS)) { return sdError(SD_CARD_ERROR_ACMD41); } } while ((SDHC_CMDRSP0 & 0x80000000) == 0); m_ocr = SDHC_CMDRSP0; if (SDHC_CMDRSP0 & 0x40000000) { // Is high capacity. m_highCapacity = true; } if (!cardCommand(CMD2_XFERTYP, 0)) { return sdError(SD_CARD_ERROR_CMD2); } if (!cardCommand(CMD3_XFERTYP, 0)) { return sdError(SD_CARD_ERROR_CMD3); } m_rca = SDHC_CMDRSP0 & 0xFFFF0000; if (!readReg16(CMD9_XFERTYP, &m_csd)) { return sdError(SD_CARD_ERROR_CMD9); } if (!readReg16(CMD10_XFERTYP, &m_cid)) { return sdError(SD_CARD_ERROR_CMD10); } if (!cardCommand(CMD7_XFERTYP, m_rca)) { return sdError(SD_CARD_ERROR_CMD7); } // Set card to bus width four. if (!cardAcmd(m_rca, ACMD6_XFERTYP, 2)) { return sdError(SD_CARD_ERROR_ACMD6); } // Set SDHC to bus width four. SDHC_PROCTL &= ~SDHC_PROCTL_DTW_MASK; SDHC_PROCTL |= SDHC_PROCTL_DTW(SDHC_PROCTL_DTW_4BIT); SDHC_WML = SDHC_WML_RDWML(FIFO_WML) | SDHC_WML_WRWML(FIFO_WML); // Determine if High Speed mode is supported and set frequency. uint8_t status[64]; if (cardCMD6(0X00FFFFFF, status) && (2 & status[13]) && cardCMD6(0X80FFFFF1, status) && (status[16] & 0XF) == 1) { kHzSdClk = 50000; } else { kHzSdClk = 25000; } // disable GPIO enableGPIO(false); // Set the SDHC SCK frequency. setSdclk(kHzSdClk); // enable GPIO enableGPIO(true); m_initDone = true; return true; }
/*************************************************** * initialize all software and hardware * scalerVS_init() ****************************************************/ STATIC long scalerVS_init(int after) { volatile char *localAddr; unsigned long status; char *baseAddr; int card, card_type; uint32 probeValue = 0; Debug(2,"scalerVS_init(): entry, after = %d\n", after); if (after || (vs_num_cards == 0)) return(0); /* allocate scalerVS_state structures, array of pointers */ if (scalerVS_state == NULL) { scalerVS_state = (struct scalerVS_state **) calloc(1, vs_num_cards * sizeof(struct scalerVS_state *)); scalerVS_total_cards=0; for (card=0; card<vs_num_cards; card++) { scalerVS_state[card] = (struct scalerVS_state *) calloc(1, sizeof(struct scalerVS_state)); } } /* Check out the hardware. */ for (card=0; card<vs_num_cards; card++) { baseAddr = (char *)(vs_addrs + card*CARD_ADDRESS_SPACE); /* Can we reserve the required block of VME address space? */ status = devRegisterAddress(__FILE__, atVMEA16, (size_t)baseAddr, CARD_ADDRESS_SPACE, (volatile void **)&localAddr); if (!RTN_SUCCESS(status)) { errPrintf(status, __FILE__, __LINE__, "Can't register 2048-byte block in VME A16 at address %p\n", baseAddr); return (ERROR); } if (devReadProbe(4,(volatile void *)(localAddr+READ_XFER_REG_OFFSET),(void*)&probeValue)) { printf("scalerVS_init: no VSxx card at %p\n",localAddr); return(0); } /* Declare victory. */ Debug(2,"scalerVS_init: we own 2048 bytes in VME A16 starting at %p\n", localAddr); scalerVS_state[card]->localAddr = localAddr; scalerVS_total_cards++; /* reset this card */ /* any write to this address causes reset */ writeReg16(localAddr,MASTER_RESET_OFFSET,0); /* get this card's type and serial number */ scalerVS_state[card]->ident = readReg16(localAddr,ID_OFFSET); Debug(3,"scalerVS_init: Serial # = %d\n", scalerVS_state[card]->ident & 0x3FF); /* get this card's type */ card_type = scalerVS_state[card]->ident >> 10; if ((card_type > 22) || (card_type < 16)) { errPrintf(status, __FILE__, __LINE__, "unrecognized module\n"); scalerVS_state[card]->num_channels = 0; scalerVS_state[card]->card_exists = 0; /* * Something's wrong with this card, but we still count it in scalerVS_total_cards. * A bad card retains its address space; otherwise we can't talk to the next one. */ } else { scalerVS_state[card]->num_channels = VS_module_types[card_type-16].num_channels; scalerVS_state[card]->card_exists = 1; } Debug(3,"scalerVS_init: nchan = %d\n", scalerVS_state[card]->num_channels); } Debug(3,"scalerVS_init: Total cards = %d\n\n",scalerVS_total_cards); #ifdef vxWorks if (epicsAtExit(scalerVS_shutdown, 0) < 0) epicsPrintf ("scalerVS_init: epicsAtExit() failed\n"); #endif Debug(3,"%s", "scalerVS_init: scalers initialized\n"); return(0); }
// Return true if ok. boolean readAccumCharge(uint16* value) { return readReg16(regs16::kAccumCharge, value); }