/************************************************************************************ * boc.c * * synopsis: This file contains routines which handle setting and recalling BOC * varaibles. * * in this file: bocRegDecode, setBocVariable, getBocVariable. * * related files: * ABCDConfig.c: Routines for setting & retrieving SCT chip & BOC variables * from the configuration structure set. * pixelUtilities.c: Routines for setting & retrieving Pixel chip & BOC variables * from the configuration structure set. ************************************************************************************/ #include #include #include #include #include #include #include "resources.h" #include "registerIndices.h" #include "bocStructure.h" #include "accessRegister.h" extern char genStr[]; extern TIMER_Handle timer1; /* general purpose timer, started in main() */ #pragma CODE_SECTION(bocRegDecode, "xcode"); #pragma CODE_SECTION(setBocVariable, "xcode"); #pragma CODE_SECTION(getBocVariable, "xcode"); #pragma DATA_SECTION(bocConfig,"bocData"); //BOCConfig bocConfig[N_MODULE_CONFIG_SETS]; BOCConfig bocConfig; /************************************************************************************ * bocRegDecode * * synopsis: Translates from the register ID (with embedded link number) * used in rwRegField to the equivalent BOC register & link number. * * author: Douglas Ferguson ************************************************************************************/ void bocRegDecode(UINT32 id, UINT8 *bocReg, UINT8 *link) { *bocReg= BOC_VAR_STAT; *link= 0; if ((id >= FINE_DELAY(0)) && (id <= FINE_DELAY(47))) { *bocReg= BOC_VAR_TXFINE; *link= id -FINE_DELAY(0); } else if ((id >= COARSE_DELAY(0)) && (id <= COARSE_DELAY(47))) { *bocReg= BOC_VAR_TXCOARSE; *link= id -COARSE_DELAY(0); } else if ((id >= MARK_SPACE(0)) && (id <= MARK_SPACE(47))) { *bocReg= BOC_VAR_TXMARKSPACE; *link= id -MARK_SPACE(0); } else if ((id >= STREAM_INHIBIT_MASK(0)) && (id <= STREAM_INHIBIT_MASK(47))) { *bocReg= BOC_VAR_TXINHIBIT; *link= id -STREAM_INHIBIT_MASK(0); } else if ((id >= LASER_CURR_DAC(0)) && (id <= LASER_CURR_DAC(47))) { *bocReg= BOC_VAR_TXCURRENT; *link= id -LASER_CURR_DAC(0); } //dpsf: strobe delay is gone I think? else if ((id >= IN_DATA_RX_THRESH_DAC(0)) && (id <= IN_DATA_RX_THRESH_DAC(95))) { *bocReg= BOC_VAR_RXTHRESHOLD; *link= id -IN_DATA_RX_THRESH_DAC(0); } else if ((id >= IN_LINK_DATA_DELAY(0)) && (id <= IN_LINK_DATA_DELAY(95))) { *bocReg= BOC_VAR_RXDELAY; *link= id -IN_LINK_DATA_DELAY(0); } else if (id == BPM_CLOCK_PHASE) *bocReg= BOC_VAR_BPM_CLOCK_PHASE; else if (id == BREG_CLOCK_PHASE) *bocReg= BOC_VAR_BREG_CLOCK_PHASE; else if (id == VERNIER_CLOCK_STEP_PHASE0) *bocReg= BOC_VAR_VERNIER_CLOCK_STEPPHASE0; else if (id == VERNIER_CLOCK_STEP_PHASE1) *bocReg= BOC_VAR_VERNIER_CLOCK_STEPPHASE1; else if (id == VERNIER_CLOCK_FINE_PHASE) *bocReg= BOC_VAR_VERNIER_CLOCK_FINEPHASE; else if (id == BOC_RESET) *bocReg= BOC_VAR_BOCRESET; else if (id == BPM_RESET) *bocReg= BOC_VAR_BPMRESET; else if (id == TX_DAC_CLEAR) *bocReg= BOC_VAR_TXDAC_CLEAR; else if (id == RX_DAC_CLEAR) *bocReg= BOC_VAR_RXDAC_CLEAR; else if (id == RX_DATA_MODE) *bocReg= BOC_VAR_RXDATAMODE; else if (id == CLOCK_CONTROL_BITS) *bocReg= BOC_VAR_CLOCKCTRLBITS; else if (id == BOC_STATUS) *bocReg= BOC_VAR_STAT; else if (id == BOC_FIRMWARE_VERSION) *bocReg= BOC_VAR_FIRMWARE_REV; else if (id == BOC_HARDWARE_VERSION) *bocReg= BOC_VAR_HARDWARE_REV; else if (id == BOC_MODULE_TYPE) *bocReg= BOC_VAR_MODULETYPE; else if (id == BOC_MANUFACTURER) *bocReg= BOC_VAR_MNFT; else if (id == BOC_SERIAL_NUMBER) *bocReg= BOC_VAR_SERIALNO; } /************************************************************************************ * setBocVariable * * synopsis: Sets the indicated BOC variable and stores the changed setting inside * the BOC structure, or returns an error if the variable is read-only. * * author: Douglas Ferguson ************************************************************************************/ INT32 setBocVariable(UINT8 link, UINT8 type, UINT8 val) { INT32 returnCode= SUCCESS; UINT32 t0, bocBusyStat; UINT8 paramError= FALSE; /* bocBusyStat indicates two possible errors: there is no BOC Card, or a previous operation is not yet complete. If the latter, give it up to 5 micro-seconds to complete. */ t0= TIMER_getCount(timer1); do { readRegister(RRIF_STATUS_1, 1,BOC_BUSY_O, &bocBusyStat); } while (bocBusyStat && (delta_t(t0)<50)); if (bocBusyStat) { newError(&returnCode, BOC_INITIALLY_BUSY, FATAL_ERR, "setBocVariable", "BOC not present or previous operation not completing.\n", __FILE__, __LINE__ ); return returnCode; } switch(type) { case BOC_VAR_TXFINE: writeRegisterDirect(FINE_DELAY(link),FINE_DELAY_W,FINE_DELAY_O, val); bocConfig.bocTxParams[link].txFineDelay= val; break; case BOC_VAR_TXCOARSE: writeRegisterDirect(COARSE_DELAY(link),COARSE_DELAY_W,COARSE_DELAY_O, val); bocConfig.bocTxParams[link].txCoarseDelay= val; break; case BOC_VAR_TXMARKSPACE: writeRegisterDirect(MARK_SPACE(link), MARK_SPACE_W, MARK_SPACE_O, val); bocConfig.bocTxParams[link].txMarkSpace= val; break; case BOC_VAR_TXINHIBIT: writeRegisterDirect(STREAM_INHIBIT_MASK(link), BOC_STREAM_INHIBIT_W, BOC_STREAM_INHIBIT_O, val); bocConfig.bocTxParams[link].txStreamInhibit= val; break; case BOC_VAR_TXCURRENT: writeRegisterDirect(LASER_CURR_DAC(link), LASER_CURR_DAC_W, LASER_CURR_DAC_O, val); bocConfig.bocTxParams[link].txCurrent= val; break; case BOC_VAR_RXTHRESHOLD: writeRegisterDirect(IN_DATA_RX_THRESH_DAC(link), IN_DATA_RX_THRESH_W, IN_DATA_RX_THRESH_O, val); bocConfig.bocRxParams[link].rxThreshold= val; break; case BOC_VAR_RXDELAY: writeRegisterDirect(IN_LINK_DATA_DELAY(link),IN_LINK_DATA_DELAY_W, IN_LINK_DATA_DELAY_O, val); bocConfig.bocRxParams[link].rxDelay= val; break; case BOC_VAR_BPM_CLOCK_PHASE: writeRegisterDirect(BPM_CLOCK_PHASE, BPM_CLOCK_PHASE_W, BPM_CLOCK_PHASE_O, val); bocConfig.bocGlobalParams.bpmClockPhase = val; break; case BOC_VAR_BREG_CLOCK_PHASE: writeRegisterDirect(BREG_CLOCK_PHASE, BREG_CLOCK_PHASE_W, BREG_CLOCK_PHASE_O, val); bocConfig.bocGlobalParams.bRegClockPhase = val; break; case BOC_VAR_VERNIER_CLOCK_STEPPHASE0: writeRegisterDirect(VERNIER_CLOCK_STEP_PHASE0, VERNIER_CLOCK_STEP_PHASE0_W, VERNIER_CLOCK_STEP_PHASE0_O, val); bocConfig.bocGlobalParams.vernierClockStepPhase[0] = val; break; case BOC_VAR_VERNIER_CLOCK_STEPPHASE1: writeRegisterDirect(VERNIER_CLOCK_STEP_PHASE1, VERNIER_CLOCK_STEP_PHASE1_W, VERNIER_CLOCK_STEP_PHASE1_O, val); bocConfig.bocGlobalParams.vernierClockStepPhase[1] = val; break; case BOC_VAR_VERNIER_CLOCK_FINEPHASE: writeRegisterDirect(VERNIER_CLOCK_FINE_PHASE, VERNIER_CLOCK_FINE_PHASE_W, VERNIER_CLOCK_FINE_PHASE_O, val); bocConfig.bocGlobalParams.vernierClockFinePhase = val; break; /* Self-clearing registers? John says 'no' */ case BOC_VAR_BOCRESET: //writeRegisterDirect(BOC_RESET, BOC_RESET_W, BOC_RESET_O, val); writeRegisterDirect(BOC_RESET, BOC_RESET_W, BOC_RESET_O, 1); delay(30); writeRegisterDirect(BOC_RESET, BOC_RESET_W, BOC_RESET_O, 0); break; case BOC_VAR_BPMRESET: //writeRegisterDirect(BPM_RESET, BPM_RESET_W, BPM_RESET_O, val); writeRegisterDirect(BPM_RESET, BPM_RESET_W, BPM_RESET_O, 1); delay(30); writeRegisterDirect(BPM_RESET, BPM_RESET_W, BPM_RESET_O, 0); break; case BOC_VAR_TXDAC_CLEAR: //writeRegisterDirect(TX_DAC_CLEAR, TX_DAC_CLEAR_W, TX_DAC_CLEAR_O, val); writeRegisterDirect(TX_DAC_CLEAR, TX_DAC_CLEAR_W, TX_DAC_CLEAR_O, 1); delay(30); writeRegisterDirect(TX_DAC_CLEAR, TX_DAC_CLEAR_W, TX_DAC_CLEAR_O, 0); break; case BOC_VAR_RXDAC_CLEAR: //writeRegisterDirect(RX_DAC_CLEAR, RX_DAC_CLEAR_W, RX_DAC_CLEAR_O, val); writeRegisterDirect(RX_DAC_CLEAR, RX_DAC_CLEAR_W, RX_DAC_CLEAR_O, 1); delay(30); writeRegisterDirect(RX_DAC_CLEAR, RX_DAC_CLEAR_W, RX_DAC_CLEAR_O, 0); break; case BOC_VAR_RXDATAMODE: writeRegisterDirect(RX_DATA_MODE, RX_DATA_MODE_W, RX_DATA_MODE_O, val); bocConfig.bocGlobalParams.rxDataMode = val; break; case BOC_VAR_CLOCKCTRLBITS: writeRegisterDirect(CLOCK_CONTROL_BITS, CLOCK_CONTROL_BITS_W, CLOCK_CONTROL_BITS_O, val); bocConfig.bocGlobalParams.clockCtrlBits = val; break; case BOC_VAR_STAT: case BOC_VAR_FIRMWARE_REV: case BOC_VAR_HARDWARE_REV: case BOC_VAR_MODULETYPE: case BOC_VAR_MNFT: case BOC_VAR_SERIALNO: paramError= TRUE; sprintf(genStr, "%s0x%02x%s", "BOC variable ", type, " is read-only.\n"); break; default: paramError= TRUE; sprintf(genStr, "%s0x%02x%s", "Illegal BOC variable (", type, ").\n"); } //end of switch(type) if (paramError) { newError(&returnCode, PARAM_ERROR, FATAL_ERR, "setBocVariable", genStr, __FILE__, __LINE__); } else { t0= TIMER_getCount(timer1); do { readRegister(RRIF_STATUS_1, 1,BOC_BUSY_O, &bocBusyStat); } while (bocBusyStat && (delta_t(t0)<50)); if (bocBusyStat) { newError(&returnCode, BOC_CONT_BUSY, FATAL_ERR, "setBocVariable", "The BOC failed to complete the operation within 5 micro-seconds.\n", __FILE__, __LINE__ ); return returnCode; } } return returnCode; } /************************************************************************************ * getBocVariable * * synopsis: Retrieves the indicated BOC variable and stores the setting inside * the BOC structure. Some BOC variables are write-only; for these * variables the current setting of the BOC structure is returned. * * author: Douglas Ferguson ************************************************************************************/ INT32 getBocVariable(UINT8 link, UINT8 type, UINT8 *val) { INT32 returnCode= SUCCESS; UINT32 t0, bocBusyStat, val32; UINT8 paramError= FALSE; /* bocBusyStat indicates two possible errors: there is no BOC Card, or a previous operation is not yet complete. If the latter, give it up to 5 micro-seconds to complete. */ t0= TIMER_getCount(timer1); do { readRegister(RRIF_STATUS_1, 1,BOC_BUSY_O, &bocBusyStat); } while (bocBusyStat && (delta_t(t0)<50)); if (bocBusyStat) { newError(&returnCode, BOC_INITIALLY_BUSY, FATAL_ERR, "getBocVariable", "BOC not present or previous operation not completing.\n", __FILE__, __LINE__ ); *val= 0; return returnCode; } switch(type) { case BOC_VAR_TXFINE: readRegister(FINE_DELAY(link),FINE_DELAY_W,FINE_DELAY_O, &val32); bocConfig.bocTxParams[link].txFineDelay= *val= (UINT8) val32; break; case BOC_VAR_TXCOARSE: readRegister(COARSE_DELAY(link),COARSE_DELAY_W,COARSE_DELAY_O, &val32); bocConfig.bocTxParams[link].txCoarseDelay= *val= (UINT8) val32; break; case BOC_VAR_TXMARKSPACE: readRegister(MARK_SPACE(link), MARK_SPACE_W, MARK_SPACE_O, &val32); bocConfig.bocTxParams[link].txMarkSpace= *val= (UINT8) val32; break; case BOC_VAR_TXINHIBIT: readRegister(STREAM_INHIBIT_MASK(link), BOC_STREAM_INHIBIT_W, BOC_STREAM_INHIBIT_O, &val32); bocConfig.bocTxParams[link].txStreamInhibit= *val= (UINT8) val32; break; case BOC_VAR_TXCURRENT: /* Write-only? */ //readRegister(LASER_CURR_DAC(link), LASER_CURR_DAC_W, // LASER_CURR_DAC_O, &val32); *val= bocConfig.bocTxParams[link].txCurrent; //= *val; break; case BOC_VAR_RXTHRESHOLD: /* Write-only? */ //readRegister(IN_DATA_RX_THRESH_DAC(link), IN_DATA_RX_THRESH_W, // IN_DATA_RX_THRESH_O, &val32); *val= bocConfig.bocRxParams[link].rxThreshold; //= *val; break; case BOC_VAR_RXDELAY: /* Write-only? */ //readRegister(IN_LINK_DATA_DELAY(link),IN_LINK_DATA_DELAY_W, // IN_LINK_DATA_DELAY_O, &val32); *val= bocConfig.bocRxParams[link].rxDelay; //= *val; break; case BOC_VAR_BPM_CLOCK_PHASE: /* ? */ readRegister(BPM_CLOCK_PHASE, BPM_CLOCK_PHASE_W, BPM_CLOCK_PHASE_O, &val32); bocConfig.bocGlobalParams.bpmClockPhase = *val= (UINT8) val32; break; case BOC_VAR_BREG_CLOCK_PHASE: readRegister(BREG_CLOCK_PHASE, BREG_CLOCK_PHASE_W, BREG_CLOCK_PHASE_O, &val32); bocConfig.bocGlobalParams.bRegClockPhase = *val= (UINT8) val32; break; case BOC_VAR_VERNIER_CLOCK_STEPPHASE0: readRegister(VERNIER_CLOCK_STEP_PHASE0, VERNIER_CLOCK_STEP_PHASE0_W, VERNIER_CLOCK_STEP_PHASE0_O, &val32); bocConfig.bocGlobalParams.vernierClockStepPhase[0] = *val= (UINT8) val32; break; case BOC_VAR_VERNIER_CLOCK_STEPPHASE1: readRegister(VERNIER_CLOCK_STEP_PHASE1, VERNIER_CLOCK_STEP_PHASE1_W, VERNIER_CLOCK_STEP_PHASE1_O, &val32); bocConfig.bocGlobalParams.vernierClockStepPhase[1] = *val= (UINT8) val32; break; case BOC_VAR_VERNIER_CLOCK_FINEPHASE: readRegister(VERNIER_CLOCK_FINE_PHASE, VERNIER_CLOCK_FINE_PHASE_W, VERNIER_CLOCK_FINE_PHASE_O, &val32); bocConfig.bocGlobalParams.vernierClockFinePhase = *val= (UINT8) val32; break; /* Self-clearing registers? */ case BOC_VAR_BOCRESET: readRegister(BOC_RESET, BOC_RESET_W, BOC_RESET_O, &val32); bocConfig.bocGlobalParams.bocReset = *val= (UINT8) val32; break; case BOC_VAR_BPMRESET: readRegister(BPM_RESET, BPM_RESET_W, BPM_RESET_O, &val32); bocConfig.bocGlobalParams.bpmReset = *val= (UINT8) val32; break; case BOC_VAR_TXDAC_CLEAR: readRegister(TX_DAC_CLEAR, TX_DAC_CLEAR_W, TX_DAC_CLEAR_O, &val32); bocConfig.bocGlobalParams.txDacClear = *val= (UINT8) val32; break; case BOC_VAR_RXDAC_CLEAR: readRegister(RX_DAC_CLEAR, RX_DAC_CLEAR_W, RX_DAC_CLEAR_O, &val32); bocConfig.bocGlobalParams.rxDacClear = *val= (UINT8) val32; break; case BOC_VAR_RXDATAMODE: readRegister(RX_DATA_MODE, RX_DATA_MODE_W, RX_DATA_MODE_O, &val32); bocConfig.bocGlobalParams.rxDataMode = *val= (UINT8) val32; break; case BOC_VAR_CLOCKCTRLBITS: readRegister(CLOCK_CONTROL_BITS, CLOCK_CONTROL_BITS_W, CLOCK_CONTROL_BITS_O, &val32); bocConfig.bocGlobalParams.clockCtrlBits = *val= (UINT8) val32; break; case BOC_VAR_STAT: readRegister(BOC_STATUS, BOC_STATUS_W, BOC_STATUS_O, &val32); bocConfig.bocGlobalParams.status = *val= (UINT8) val32; break; case BOC_VAR_FIRMWARE_REV: readRegister(BOC_FIRMWARE_VERSION, BOC_FIRMWARE_VERSION_W, BOC_FIRMWARE_VERSION_O, &val32); bocConfig.bocGlobalParams.firmwareRev = *val= (UINT8) val32; break; case BOC_VAR_HARDWARE_REV: readRegister(BOC_HARDWARE_VERSION, BOC_HARDWARE_VERSION_W, BOC_HARDWARE_VERSION_O, &val32); bocConfig.bocGlobalParams.hardwareRev = *val= (UINT8) val32; break; case BOC_VAR_MODULETYPE: readRegister(BOC_MODULE_TYPE, BOC_MODULE_TYPE_W, BOC_MODULE_TYPE_O, &val32); bocConfig.bocGlobalParams.moduleType = *val= (UINT8) val32; break; case BOC_VAR_MNFT: readRegister(BOC_MANUFACTURER, BOC_MANUFACTURER_W, BOC_MANUFACTURER_O, &val32); bocConfig.bocGlobalParams.manufacturer = *val= (UINT8) val32; break; case BOC_VAR_SERIALNO: readRegister(BOC_SERIAL_NUMBER, BOC_SERIAL_NUMBER_W, BOC_SERIAL_NUMBER_O, &val32); bocConfig.bocGlobalParams.serialNumber = *val= (UINT8) val32; break; default: paramError= TRUE; sprintf(genStr, "%s0x%02x%s", "Illegal BOC variable (", type, ").\n"); } //end of switch(type) if (paramError) { newError(&returnCode, PARAM_ERROR, FATAL_ERR, "setBocVariable", genStr, __FILE__, __LINE__); } else { t0= TIMER_getCount(timer1); do { readRegister(RRIF_STATUS_1, 1,BOC_BUSY_O, &bocBusyStat); } while (bocBusyStat && (delta_t(t0)<50)); if (bocBusyStat) { newError(&returnCode, BOC_CONT_BUSY, FATAL_ERR, "setBocVariable", "The BOC failed to complete the operation within 5 micro-seconds.\n", __FILE__, __LINE__ ); return returnCode; } } return returnCode; }