void start_fpga(NiFpga_Session* session, NiFpga_Status* status) { // must be called before any other calls *status = NiFpga_Initialize(); printf("initializing FPGA read AI AO\n"); printf("bitfile expected at:\n"); printf(NiFpga_FPGA_read_ai_ao_Bitfile); printf("\n"); //printf("Current working dir: %s\n", strcat(cwd, '../labview_fpga_lib/read_ai_ao/')); if (NiFpga_IsNotError(*status)) { // opens a session, downloads the bitstream, and runs the FPGA NiFpga_MergeStatus(status, NiFpga_Open(NiFpga_FPGA_read_ai_ao_Bitfile, NiFpga_FPGA_read_ai_ao_Signature, "RIO0", NiFpga_OpenAttribute_NoRun, session)); if (NiFpga_IsNotError(*status)) { // run the FPGA application NiFpga_MergeStatus(status, NiFpga_Run(*session, 0)); } else{ // print warning printf("error occurred at FPGA open"); printf("%d", *status); } } fflush(stdout); }
void stop_fpga(NiFpga_Session* session, NiFpga_Status* status) { // close the session now that we're done NiFpga_MergeStatus(status, NiFpga_Close(*session, 0)); // must be called after all other calls NiFpga_MergeStatus(status, NiFpga_Finalize()); }
// Closes the FPGA session void FPGA_Close(void) { // close the session now that we're done printf("Closing the session..."); if (NiFpga_IsNotError(FPGA_Status)) { NiFpga_MergeStatus(&FPGA_Status, NiFpga_Close(FPGA_Session, 0)); } // must be called after all other calls printf("Finalizing..."); NiFpga_MergeStatus(&FPGA_Status, NiFpga_Finalize()); }
void FPGA_SetPIDdt(uint16_t dt) { NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteU16(FPGA_Session,NiFpga_mainFPGA_ControlU16_PIDdt, dt)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Set PID dt failed"); } }
int16_t read_AI2(NiFpga_Session* session, NiFpga_Status* status) { int16_t value; NiFpga_MergeStatus(status, NiFpga_ReadI16(*session,NiFpga_FPGA_read_ai_ao_IndicatorI16_Connector1AI2,&value)); return value; }
void FPGA_setLPIDIntGain(int16_t gain) { NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteI16(FPGA_Session,NiFpga_mainFPGA_ControlI16_LPIDIntGain,gain)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Set left PID integral gain failed"); } }
// Sets the sabertooth address void FPGA_setSabertoothAddress(uint8_t address) { NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteU8(FPGA_Session,NiFpga_mainFPGA_ControlU8_SerialAddress, address)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Failed to set Sabertooth Address"); } }
void FPGA_setMaxPIDSpeed(uint16_t max) { NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteU16(FPGA_Session,NiFpga_mainFPGA_ControlU16_maxPIDSpeedTicksPerDt, max)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Set max PID speed failed"); } }
void FPGA_setRPIDDerGain(int16_t gain) { NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteI16(FPGA_Session,NiFpga_mainFPGA_ControlI16_RPIDDerGain,gain)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Set right PID derivative gain failed"); } }
int16_t FPGA_GetCRIOVLineRead() { int16_t retval; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadI16(FPGA_Session,NiFpga_mainFPGA_IndicatorI16_cRIOVMonitormV,&retval)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get cRIOV Line Read Failed."); } return retval; }
uint16_t FPGA_GetRCCH3() { uint16_t retval; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadU16(FPGA_Session,NiFpga_mainFPGA_IndicatorU16_C3Mode,&retval)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get RC CH3 Read Failed."); } return retval; }
int16_t FPGA_GetVersion() { int16_t version; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadI16(FPGA_Session,NiFpga_mainFPGA_IndicatorI16_FPGAVersion,&version)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get FPGA Version Failed."); } return version; }
void FPGA_SetMotorStatus(int value) { if(value) { NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteBool(FPGA_Session,NiFpga_mainFPGA_ControlBool_enableMotors,NiFpga_True)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Set Motor Status Failed."); } } else { NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteBool(FPGA_Session,NiFpga_mainFPGA_ControlBool_enableMotors,NiFpga_False)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Set Motor Status Failed."); } } }
int32_t FPGA_GetGPSArrayData(uint8_t * data, uint32_t length) { NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadArrayU8(FPGA_Session, NiFpga_mainFPGA_IndicatorArrayU8_GPSPOSBytes, data, length)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("GetArrayFailed"); } return 0; }
// Returns the tick value of the right motor int32_t FPGA_GetRightMotorTicks() { int32_t ticks; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadI32(FPGA_Session,NiFpga_mainFPGA_IndicatorI32_RPosMotor,&ticks)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get Right Motor Ticks Failed."); } return ticks; }
int16_t FPGA_GetYawRef() { int16_t value; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadI16(FPGA_Session,NiFpga_mainFPGA_IndicatorI16_YawRefmV,&value)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get Yaw Ref Failed."); } LOG.DATA("YawRef = %d",value); return value; }
// Returns the tick value on the right wheel int32_t FPGA_GetRightWheelTicks() { int32_t ticks; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadI32(FPGA_Session,NiFpga_mainFPGA_IndicatorI32_RPosWheel,&ticks)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get Right Wheel Ticks Failed."); } LOG.DATA("RwT = %d",ticks); return ticks; }
// Returns the velocity of the left motor float FPGA_GetLeftMotorVelocity() { int16_t ticks; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadI16(FPGA_Session,NiFpga_mainFPGA_IndicatorI16_LeftMotorVTicksPerDt,&ticks)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get Left Motor Velocity Failed."); } float Speed = ticks /leftWheelConversionConstant; LOG.DATA("LMV = %f",Speed); return Speed; }
float FPGA_GetCompassHeading(void) { uint32_t current; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadU32(FPGA_Session,NiFpga_mainFPGA_IndicatorU32_HeadingFloat,¤t)); if(NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get Compass Heading Failed"); } float out; out = *((float *)¤t); LOG.DATA("Compass %f",out); return out; }
/** * Sets options for the encoder configuration register. * * @param[in] channel A struct containing the registers on the encoder channel * to modify. * @param[in] mask Array of flags that indicate which of the configure * settings are valid. * @param[in] settings Array of flags that indicate the configuration settings. */ void Encoder_Configure(MyRio_Encoder* channel, Encoder_ConfigureMask mask, Encoder_ConfigureSettings settings) { NiFpga_Status status; uint8_t cnfgValue; /* * Get the current value of the configure register. * * The returned NiFpga_Status value is stored for error checking. */ status = NiFpga_ReadU8(myrio_session, channel->cnfg, &cnfgValue); /* * Check if there was an error reading from the encoder registers. * * If there was an error then the rest of the function cannot complete * correctly so print an error message to stdout and return from the * function early. */ MyRio_ReturnIfNotSuccess(status, "Could not read from the encoder configure registers!") /* * Clear the value of the masked bits in the configure register. This is * done so that the correct value can be set later on. */ cnfgValue = cnfgValue & (~mask); /* * Set the value of the settings in the configure register. If the * value to set is 0 this operation would not work unless the bit was * previously cleared. */ cnfgValue = cnfgValue | settings; /* * Write the new value of the configure register to the device. */ NiFpga_MergeStatus(&status, NiFpga_WriteU8(myrio_session, channel->cnfg, cnfgValue)); /* * Check if there was an error writing to encoder configure registers. * * If there was an error then print an error message to stdout. */ MyRio_ReturnIfNotSuccess(status, "Could not write to the encoder configure registers!") }
uint32_t FPGA_IsGPSNew(void) { uint32_t current; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadU32(FPGA_Session,NiFpga_mainFPGA_IndicatorU32_GPSPOSCount,¤t)); if(NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get GPS Counter Failed"); } if(current != FPGA_IsGPSNewPrevious) { FPGA_IsGPSNewPrevious = current; return 1; } return 0; }
uint32_t FPGA_IsCompassNew(void) { uint32_t current; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadU32(FPGA_Session,NiFpga_mainFPGA_IndicatorU32_CompassResponseCount,¤t)); if(NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get Compass Counter Failed"); } if(current != FPGA_IsCompassNewPrevious) { current = FPGA_IsCompassNewPrevious; return 1; } return 0; }
// Sets the left wheel velocity void FPGA_SetLeftWheelVelocity(float MetersPerSecond) { /* Check if NAN */ if (MetersPerSecond != MetersPerSecond) { MetersPerSecond = 0.0; LOG.ERR("Left Wheel command was NaN. Sending 0 instead"); } int16_t ticks = MetersPerSecond * leftWheelConversionConstant; LOG.DATA("LwT Commanded: %d for %f", ticks, MetersPerSecond); NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteI16(FPGA_Session,NiFpga_mainFPGA_ControlI16_PIDLCmdTicksPerDt,ticks)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Setting Left Wheel Velocity Failed."); } }
uint8_t FPGA_GetRCESTOP() { NiFpga_Bool rcestop; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadBool(FPGA_Session,NiFpga_mainFPGA_IndicatorBool_RCeSTOP,&rcestop)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get RCEStop Failed."); } if(rcestop == NiFpga_False) { LOG.DATA("RCEstop = False"); return 0; } else { LOG.DATA("RCEStop = True"); return 1; } }
uint8_t FPGA_GetESTOPTriggered() { NiFpga_Bool ReStopTriggered; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadBool(FPGA_Session,NiFpga_mainFPGA_IndicatorBool_eSTOPTriggered,&ReStopTriggered)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get EStop Status Failed."); } if(ReStopTriggered == NiFpga_False) { LOG.DATA("EStopTriggered = False"); return 0; } else { LOG.DATA("EStopTriggered = True"); return 1; } return 0; }
uint8_t FPGA_GetRCOn() { NiFpga_Bool RC; NiFpga_MergeStatus(&FPGA_Status,NiFpga_ReadBool(FPGA_Session,NiFpga_mainFPGA_IndicatorBool_RCOn,&RC)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Get RCon Status Failed."); } if(RC == NiFpga_False) { LOG.DATA("RCOn = False"); return 0; } else { LOG.DATA("RCOn = True"); return 1; } return 0; }
// Initializes the FPGA, the sabertooth and the mototrs void FPGA_Boot(void) { LOG.INFO("Initializing FPGA..."); FPGA_Status = NiFpga_Initialize(); if (NiFpga_IsNotError(FPGA_Status)) { // opens a session, downloads the bitstream, and runs the FPGA. LOG.INFO("Opening a session FPGA..."); NiFpga_MergeStatus(&FPGA_Status, NiFpga_Open(NiFpga_mainFPGA_Bitfile, NiFpga_mainFPGA_Signature, "RIO0", NiFpga_OpenAttribute_NoRun, &FPGA_Session)); if (NiFpga_IsNotError(FPGA_Status)) { LOG.INFO("ReDownloading the FPGA"); NiFpga_MergeStatus(&FPGA_Status,NiFpga_Download(FPGA_Session)); if (NiFpga_IsNotError(FPGA_Status)) { LOG.INFO("Restarting the FPGA"); NiFpga_MergeStatus(&FPGA_Status,NiFpga_Reset(FPGA_Session)); if (NiFpga_IsNotError(FPGA_Status)) { LOG.INFO("Running the FPGA"); NiFpga_MergeStatus(&FPGA_Status,NiFpga_Run(FPGA_Session, 0)); if (NiFpga_IsNotError(FPGA_Status)) { } else { LOG.ERR("FPGA Fail to run fpga %d ",FPGA_Status); } } else { LOG.ERR("FPGA Fail to redownload fpga %d ",FPGA_Status); } } else { LOG.ERR("FPGA Fail to redownload fpga %d ",FPGA_Status); } } else { LOG.ERR("FPGA Fail to open a session. Error Code %d ",FPGA_Status); } } LOG.VERBOSE("Reading Constants for the fpga"); if(fileExists("config/odometry.ini")) { dictionary* config = iniparser_load("config/odometry.ini"); leftWheelConversionConstant = 1/(iniparser_getdouble(config,"MotorEncoderConstant:MeterPerTickLeft",0)) * PIDUpdateRateInMs/1000; rightWheelConversionConstant = 1/(iniparser_getdouble(config,"MotorEncoderConstant:MeterPerTickRight",0)) * PIDUpdateRateInMs/1000; iniparser_freedict(config); LOG.VERBOSE("Odometry Ini file loaded for fpga!"); } else { LOG.ERR("!!!!!!!!!!!!!!!!odomentry.ini was not found!!!!!!!!!!!!!!!!!!!!!!"); } if(fileExists("config/pid.ini")) { dictionary* config = iniparser_load("config/pid.ini"); max_pid_speed = (uint16_t) iniparser_getint(config, "Both:MaxSpeedTicksPerDt", 0); left_pid_pro_gain = iniparser_getint(config, "LeftPID:ProportionalGain",0); left_pid_int_gain = iniparser_getint(config, "LeftPID:IntegralGain",0); left_pid_der_gain = iniparser_getint(config, "LeftPID:DerivativeGain", 0); right_pid_pro_gain = iniparser_getint(config, "RightPID:ProportionalGain",0); right_pid_int_gain = iniparser_getint(config, "RightPID:IntegralGain",0); right_pid_der_gain = iniparser_getint(config, "RightPID:DerivativeGain",0); iniparser_freedict(config); LOG.VERBOSE("PID INI file loaded for FPGA"); } else { LOG.ERR("PID.ini was not found"); } if(fileExists("config/CRIO.ini")) { dictionary* config = iniparser_load("config/CRIO.ini"); sabertooth_address = (uint8_t) iniparser_getint(config, "Sabertooth:Address", 130); iniparser_freedict(config); LOG.VERBOSE("Sabertooth address loaded for FPGA"); } else { LOG.ERR("Unable to load Sabertooth address"); } NiFpga_MergeStatus(&FPGA_Status,NiFpga_WriteU8(FPGA_Session,NiFpga_mainFPGA_ControlU8_SlewRateControl, 10)); if (NiFpga_IsError(FPGA_Status)) { LOG.ERR("Failed to set Sabertooth slew rate"); } FPGA_SetPIDdt(PIDUpdateRateInMs * 1000); FPGA_setMaxPIDSpeed(max_pid_speed); FPGA_setLPIDProGain(left_pid_pro_gain); FPGA_setLPIDIntGain(left_pid_int_gain); FPGA_setLPIDDerGain(left_pid_der_gain); FPGA_setRPIDProGain(right_pid_pro_gain); FPGA_setRPIDIntGain(right_pid_int_gain); FPGA_setRPIDDerGain(right_pid_der_gain); FPGA_setSabertoothAddress(sabertooth_address); // This logs the version number LOG.INFO("FPGA VERSION = %d",FPGA_GetVersion()); LOG.INFO("Turning on the motors"); FPGA_SetMotorStatus(1); }
uint32_t FPGA_GetSonarPing_5() { uint32_t value; NiFpga_MergeStatus(&FPGA_Status, NiFpga_ReadU32(FPGA_Session, NiFpga_mainFPGA_IndicatorU32_Sonar5PWM, &value)); LOG.DATA("SonarPing 5= %d", value); return value; }
void set_AO7(int16_t value, NiFpga_Session* session, NiFpga_Status* status) { NiFpga_MergeStatus(status, NiFpga_WriteI16(*session,NiFpga_FPGA_read_ai_ao_ControlI16_Connector1AO7,value)); }
/** * Reserve the interrupt from FPGA and configure DI IRQ. * * @param[in] irqChannel A structure containing the registers and settings for a particular analog IRQ I/O to modify. * @param[in] irqContext IRQ context under which you need to reserve. * @param[in] irqNumber The IRQ number (IRQNO_MIN-IRQNO_MAX). * @param[in] count The incremental times that you use to trigger the interrupt. * @param[in] type The trigger type that you use to increment the count. * @return the configuration status. */ int32_t Irq_RegisterDiIrq(MyRio_IrqDi* irqChannel, NiFpga_IrqContext* irqContext, uint8_t irqNumber, uint32_t count, Irq_Dio_Type type) { int32_t status; uint8_t cnfgValue; uint16_t typeValue; /* * Reserve an IRQ context. IRQ contexts are single-threaded; only one thread * can wait with a particular context at any given time. To minimize jitter * when first waiting on IRQs, reserve as many contexts as the application requires. * If a context is successfully reserved, you must unreserve it later. * Otherwise a memory leak will occur. */ status = NiFpga_ReserveIrqContext(myrio_session, irqContext); /* * Check if there was an error when you reserved an IRQ. * * If there was an error, print an error message to stdout and return the configuration status. */ MyRio_ReturnStatusIfNotSuccess(status, "A required NiFpga_IrqContext was not reserved.") /* * Limit the IRQ number within a range, * if the entered value is out of range, print an error message. */ if (irqNumber > IRQNO_MAX || irqNumber < IRQNO_MIN) { printf("The specified IRQ Number is out of range.\n"); return NiMyrio_Status_IrqNumberNotUsable; } /* * Check if the IRQ number or channel value already exists in the resource list, * return the configuration status and print error message. */ status = Irq_CheckReserved(irqChannel->dioChannel, irqNumber); if (status == NiMyrio_Status_IrqNumberNotUsable) { printf("You have already registered an interrupt with the same interrupt number.\n"); return status; } else if (status == NiMyrio_Status_IrqChannelNotUsable) { printf("You have already registered an interrupt with the same channel name.\n"); return status; } /* * Write the value to the DI IRQ number register. */ status = NiFpga_WriteU8(myrio_session, irqChannel->dioIrqNumber, irqNumber); /* * Check if there was an error when your wrote to the DI IRQ number register. * * If there was an error, print an error message to stdout and return the configuration status. */ MyRio_ReturnStatusIfNotSuccess(status, "Could not write to DI IRQ number register!") /* * Write the value to the DI IRQ count register. */ status = NiFpga_WriteU32(myrio_session, irqChannel->dioCount, count); /* * Check if there was an error when you reserved an IRQ. * * If there was an error, print an error message to stdout and return the configuration status. */ MyRio_ReturnStatusIfNotSuccess(status, "Could not write to DI IRQ count register!") /* * Get the current value of the DI rising-configure register. */ status = NiFpga_ReadU8(myrio_session, irqChannel->dioIrqRisingEdge, &cnfgValue); typeValue = (uint16_t) cnfgValue; /* * Get the current value of the DI falling-configure register. * Merge it with the rising-configure register and write to typeValue. */ NiFpga_MergeStatus(&status, NiFpga_ReadU8(myrio_session, irqChannel->dioIrqFallingEdge, &cnfgValue)); typeValue = typeValue | (cnfgValue << 8); /* * Check if there was an error reading from the DI rising/falling configure registers. * * If there was an error, the rest of the function cannot execute successfully, print * an error message to stdout and return the configuration status from the earlier * execution of the function. */ MyRio_ReturnStatusIfNotSuccess(status, "Could not read from the DI rise/fall configure registers!") /* * Get the current value of the DI configure register. */ status = NiFpga_ReadU8(myrio_session, irqChannel->dioIrqEnable, &cnfgValue); /* * Check if there was an error when you reserved an IRQ. * * If there was an error, print an error message to stdout and return the configuration status. */ MyRio_ReturnStatusIfNotSuccess(status, "Could not read from the DI configure register!") /* * Configure the IRQ triggered-type for the particular digital IRQ I、O. */ if (irqChannel->dioChannel == Irq_Dio_A0) { /* * Clear the value of the masked bits in the DI configure register, then * set which IO is enabled. */ cnfgValue = cnfgValue & (~Irq_Dio_A0_Enable); cnfgValue = cnfgValue | Irq_Dio_A0_Enable; /* * Clear the value of the masked bits in the DI configure register and set the I/O to enable. */ typeValue = typeValue & (~Irq_Dio_A0_Edge); if (type == Irq_Dio_RisingEdge) { typeValue = typeValue | Irq_Dio_A0_RisingEdge; } else if (type == Irq_Dio_FallingEdge) { typeValue = typeValue | Irq_Dio_A0_FallingEdge; } else if (type == Irq_Dio_Edge) { typeValue = typeValue | Irq_Dio_A0_Edge; } } else if (irqChannel->dioChannel == Irq_Dio_A1) { /* * Clear the value of the masked bits in the DI configure register, then * set which IO is enabled. */ cnfgValue = cnfgValue & (~Irq_Dio_A1_Enable); cnfgValue = cnfgValue | Irq_Dio_A1_Enable; /* * Clear the value of the masked bits in the DI configure register, then * set the triggered type. */ typeValue = typeValue & (~Irq_Dio_A1_Edge); if (type == Irq_Dio_RisingEdge) { typeValue = typeValue | Irq_Dio_A1_RisingEdge; } else if (type == Irq_Dio_FallingEdge) { typeValue = typeValue | Irq_Dio_A1_FallingEdge; } else if (type == Irq_Dio_Edge) { typeValue = typeValue | Irq_Dio_A1_Edge; } } else if (irqChannel->dioChannel == Irq_Dio_A2) { /* * Clear the value of the masked bits in the DI configure register, then * set which IO is enabled. */ cnfgValue = cnfgValue & (~Irq_Dio_A2_Enable); cnfgValue = cnfgValue | Irq_Dio_A2_Enable; /* * Clear the value of the masked bits in the DI configure register, then * set the triggered type. */ typeValue = typeValue & (~Irq_Dio_A2_Edge); if (type == Irq_Dio_RisingEdge) { typeValue = typeValue | Irq_Dio_A2_RisingEdge; } else if (type == Irq_Dio_FallingEdge) { typeValue = typeValue | Irq_Dio_A2_FallingEdge; } else if (type == Irq_Dio_Edge) { typeValue = typeValue | Irq_Dio_A2_Edge; } } else if (irqChannel->dioChannel == Irq_Dio_A3) { /* * Clear the value of the masked bits in the DI configure register, then * set which IO is enabled. */ cnfgValue = cnfgValue & (~Irq_Dio_A3_Enable); cnfgValue = cnfgValue | Irq_Dio_A3_Enable; /* * Clear the value of the masked bits in the DI configure register, then * set the triggered type. */ typeValue = typeValue & (~Irq_Dio_A3_Edge); if (type == Irq_Dio_RisingEdge) { typeValue = typeValue | Irq_Dio_A3_RisingEdge; } else if (type == Irq_Dio_FallingEdge) { typeValue = typeValue | Irq_Dio_A3_FallingEdge; } else if (type == Irq_Dio_Edge) { typeValue = typeValue | Irq_Dio_A3_Edge; } } /* * Write the new value of the DI enable configure register to the device. */ status = NiFpga_WriteU8(myrio_session, irqChannel->dioIrqEnable, cnfgValue); /* * Check if there was an error writing to DI enable configure registers. * * If there was an error then print an error message to stdout and return configuration status. */ MyRio_ReturnStatusIfNotSuccess(status, "Could not write to the DI enable configure registers!") /* * Write the new value of the DI rise-configure register to the device. */ status = NiFpga_WriteU8(myrio_session, irqChannel->dioIrqRisingEdge, (uint8_t) typeValue); /* * Write the new value of the DI fall-configure register to the device. */ NiFpga_MergeStatus(&status, NiFpga_WriteU8(myrio_session, irqChannel->dioIrqFallingEdge, (uint8_t)(typeValue >> 8))); /* * Check if there was an error writing to DI rise/fall configure registers. * * If there was an error then print an error message to stdout. */ MyRio_ReturnStatusIfNotSuccess(status, "Could not write to the DI rise/fall configure registers!") /* * Add the channel value and IRQ number in the list. */ Irq_AddReserved(irqChannel->dioChannel, irqNumber); return NiMyrio_Status_Success; }