#include #include #include #include #include "defs.h" #include "cx9261adriver.h" #include "cx9261adriver_c.h" using namespace CX9261A; // Macro for convert enumerate #define DEFINE_ENUM_CONVERTER(enum_type) \ static inline enum_type convertToCxx(CX9261A_##enum_type value) { \ return static_cast(value); \ } // Macro for functions without parameters #define DEFINE_SIMPLE_C_WRAPPER(func_name, return_type) \ return_type CX9261A_##func_name() { \ return func_name(); \ } // Macro for functions with one passthrough parameter #define DEFINE_C_WRAPPER_ONE_PASS(func_name, param_type, return_type) \ return_type CX9261A_##func_name(param_type param) { \ return func_name(param); \ } // Macro for functions with two passthrough parameter #define DEFINE_C_WRAPPER_TWO_PASS(func_name, param0_type, param1_type, return_type) \ return_type CX9261A_##func_name(param0_type param0, param1_type param1) { return func_name(param0, param1); } // Macro for functions with one convert parameter #define DEFINE_C_WRAPPER_ONE_PTR_CONVERT(func_name, param_type, return_type) \ return_type CX9261A_##func_name(const CX9261A_##param_type *param) { \ return func_name(convertToCxx(*param)); \ } // Macro for functions with one convert parameter #define DEFINE_C_WRAPPER_ONE_CONVERT(func_name, param_type, return_type) \ return_type CX9261A_##func_name(const CX9261A_##param_type param) { \ return func_name(convertToCxx(param)); \ } // Macro for functions with one convert parameter #define DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_CONVERT(func_name, param0_type, param1_type, return_type) \ return_type CX9261A_##func_name(const CX9261A_##param0_type *param0, const CX9261A_##param1_type param1) { \ return func_name(convertToCxx(*param0), convertToCxx(param1)); \ } // Macro for functions with one pass one convert parameter #define DEFINE_C_WRAPPER_ONE_PASS_ONE_CONVERT(func_name, param0_type, param1_type, return_type) \ return_type CX9261A_##func_name(param0_type param0, const CX9261A_##param1_type param1) { \ return func_name(param0, convertToCxx(param1)); \ } // Macro for functions with one pass one convert parameter #define DEFINE_C_WRAPPER_ONE_PASS_ONE_PTR_CONVERT(func_name, param0_type, param1_type, return_type) \ return_type CX9261A_##func_name(param0_type param0, const CX9261A_##param1_type *param1) { \ return func_name(param0, convertToCxx(*param1)); \ } // Macro for functions with one convert one pass parameter #define DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_PASS(func_name, param0_type, param1_type, return_type) \ return_type CX9261A_##func_name(const CX9261A_##param0_type *param0, param1_type param1) { \ return func_name(convertToCxx(*param0), param1); \ } // Macro for functions with one pass two convert parameter #define DEFINE_C_WRAPPER_ONE_PASS_TWO_CONVERT(func_name, param0_type, param1_type, param2_type, return_type) \ return_type CX9261A_##func_name(param0_type param0, const CX9261A_##param1_type param1, const CX9261A_##param2_type param2) { \ return func_name(param0, convertToCxx(param1), convertToCxx(param2)); \ } DEFINE_ENUM_CONVERTER(WorkMode) DEFINE_ENUM_CONVERTER(TrMode) DEFINE_ENUM_CONVERTER(PortMode) DEFINE_ENUM_CONVERTER(IOMode) DEFINE_ENUM_CONVERTER(LoSource) DEFINE_ENUM_CONVERTER(RxChannel) DEFINE_ENUM_CONVERTER(TxChannel) DEFINE_ENUM_CONVERTER(PowerMode) DEFINE_ENUM_CONVERTER(NCOMode) DEFINE_ENUM_CONVERTER(TemperatureComp) DEFINE_ENUM_CONVERTER(CalibMethod) DEFINE_ENUM_CONVERTER(DCCalibMethod) // Convert AGCPDT from C to C++ static inline AGCPDT convertToCxx(const CX9261A_AGCPDT& pdt) { AGCPDT result; result.pdtN = pdt.pdtN; result.pdtM = pdt.pdtM; return result; } // Convert AGCLMT from C to C++ static inline AGCLMT convertToCxx(const CX9261A_AGCLMT& lmt) { AGCLMT result; result.count = lmt.count; result.threshold1 = lmt.threshold1; result.threshold2 = lmt.threshold2; result.threshold3 = lmt.threshold3; result.threshold4 = lmt.threshold4; return result; } // Convert AGCDIG from C to C++ static inline AGCDIG convertToCxx(const CX9261A_AGCDIG& dig) { AGCDIG result; result.count = dig.count; result.threshold1 = dig.threshold1; result.threshold2 = dig.threshold2; result.threshold3 = dig.threshold3; result.threshold4 = dig.threshold4; return result; } // Convert AGC from C to C++ static AGC convertToCxx(const CX9261A_AGC& agc) { AGC result; result.mode = agc.mode; result.pdt = convertToCxx(agc.pdt); result.lmt = convertToCxx(agc.lmt); result.dig = convertToCxx(agc.dig); return result; } // Convert Clock from C to C++ static Clock convertToCxx(const CX9261A_Clock& clock) { Clock result; result.ref = clock.ref; result.adc = clock.adc; result.refDiv = clock.refDiv; result.bbUseIntDiv = clock.bbUseIntDiv; result.refDoubler = clock.refDoubler; return result; } // Convert Calib from C to C++ static Calib convertToCxx(const CX9261A_Calib& c) { Calib result; result.calibDC = c.calibDC; result.dcTrackingLength = c.dcTrackingLength; result.dcHighPassFactor = c.dcHighPassFactor; result.rx1CalibPll = c.rx1CalibPll; result.rx2CalibPll = c.rx2CalibPll; result.rx3CalibPll = c.rx3CalibPll; result.tx1CalibPll = c.tx1CalibPll; result.tx2CalibPll = c.tx2CalibPll; result.f0 = c.f0; result.dcCalibMethod = convertToCxx(c.dcCalibMethod); result.rxMethod = convertToCxx(c.rxMethod); result.txMethod = convertToCxx(c.txMethod); if(MAX_MULTI_POINTS < c.numRxPoint) { LOGGING("Rx多点校准的频率校准数量超出限制 MAX_MULTI_POINTS"); exit(-1); } if(MAX_MULTI_POINTS < c.numTxPoint) { LOGGING("Tx多点校准的频率校准数量超出限制 MAX_MULTI_POINTS"); exit(-1); } result.rxMultiPoints.resize(c.numRxPoint); result.txMultiPoints.resize(c.numTxPoint); std::memcpy(result.rxMultiPoints.data(), c.rxMultiPoints, c.numRxPoint * sizeof(double)); std::memcpy(result.txMultiPoints.data(), c.txMultiPoints, c.numTxPoint * sizeof(double)); return result; } // Convert PllSource from C to C++ static PllSource convertToCxx(const CX9261A_PllSource& src) { PllSource result; result.rxUseExt = src.rxUseExt; result.txUseExt = src.txUseExt; result.rx1Source = convertToCxx(src.rx1Source); result.rx2Source = convertToCxx(src.rx2Source); result.rx3Source = convertToCxx(src.rx3Source); result.tx1Source = convertToCxx(src.tx1Source); result.tx2Source = convertToCxx(src.tx2Source); return result; } // Convert PllFreq from C to C++ static PllFreq convertToCxx(const CX9261A_PllFreq& freq) { PllFreq result; result.pll1Freq = freq.pll1Freq; result.pll2Freq = freq.pll2Freq; result.pll3Freq = freq.pll3Freq; result.pll4Freq = freq.pll4Freq; result.pll5Freq = freq.pll5Freq; result.rxExtFreq = freq.rxExtFreq; result.txExtFreq = freq.txExtFreq; return result; } // Convert Interface from C to C++ static Interface convertToCxx(const CX9261A_Interface& iface) { Interface result; result.workMode = convertToCxx(iface.workMode); result.trMode = convertToCxx(iface.trMode); result.portMode = convertToCxx(iface.portMode); result.ioMode = convertToCxx(iface.ioMode); return result; } // Convert TxNCO from C to C++ static TxNCO convertToCxx(const CX9261A_TxNCO& nco) { TxNCO result; result.txUseBist = nco.txUseBist; result.txNCOFreq = nco.txNCOFreq; return result; } // Convert RxNCO from C to C++ static RxNCO convertToCxx(const CX9261A_RxNCO& nco) { RxNCO result; result.rxUseBist = nco.rxUseBist; result.rxNCOBypass = nco.rxNCOBypass; result.rxNCOUpward = nco.rxNCOUpward; result.rxNCOMaster = nco.rxNCOMaster; result.rxNCOFreq = nco.rxNCOFreq; return result; } // Convert RxConfig from C to C++ static RxConfig convertToCxx(const CX9261A_RxConfig& config) { RxConfig result; result.bandwidth = config.bandwidth; result.tia = config.tia; result.mixer = config.mixer; return result; } // Convert TxConfig from C to C++ static TxConfig convertToCxx(const CX9261A_TxConfig& config) { TxConfig result; result.bandwidth = config.bandwidth; result.mixer = config.mixer; return result; } // Convert Filters from C to C++ static Filters convertToCxx(const CX9261A_Filters& filters) { Filters result; result.fir = filters.fir; result.hbf1 = filters.hbf1; result.hbf2 = filters.hbf2; result.hbf3 = filters.hbf3; result.cic = filters.cic; return result; } // Convert Power from C to C++ static Power convertToCxx(const CX9261A_Power& power) { Power result; result.dig_tx2 = power.dig_tx2; result.dig_tx1 = power.dig_tx1; result.dig_rx3 = power.dig_rx3; result.dig_rx2 = power.dig_rx2; result.dig_rx1 = power.dig_rx1; result.fref1_rx = power.fref1_rx; result.auxadc2 = power.auxadc2; result.auxadc1 = power.auxadc1; result.auxdac = power.auxdac; result.temp_sensor = power.temp_sensor; result.bgr = power.bgr; result.exlo = power.exlo; result.tx2 = power.tx2; result.tx1 = power.tx1; result.rx3 = power.rx3; result.rx2 = power.rx2; result.rx1 = power.rx1; result.pll5_ldo = power.pll5_ldo; result.pll5 = power.pll5; result.pll4_ldo = power.pll4_ldo; result.pll4 = power.pll4; result.pll3_ldo = power.pll3_ldo; result.pll3 = power.pll3; result.pll2_ldo = power.pll2_ldo; result.pll2 = power.pll2; result.pll1_ldo = power.pll1_ldo; result.pll1 = power.pll1; result.bbpll = power.bbpll; return result; } static PowerManagement convertToCxx(const CX9261A_PowerManagement& pwMgmt) { PowerManagement result; result.powerMode = convertToCxx(pwMgmt.powerMode); result.rxPower = convertToCxx(pwMgmt.rxPower); result.txPower = convertToCxx(pwMgmt.txPower); result.fddPower = convertToCxx(pwMgmt.fddPower); return result; } static CX9261A_CalibPredis convertToC(const CalibPredis& cp) { CX9261A_CalibPredis result; result.bHigh = cp.bHigh; result.bLow = cp.bLow; result.cHigh = cp.cHigh; result.cLow = cp.cLow; result.dciHigh = cp.dciHigh; result.dciLow = cp.dciLow; result.dcqHigh = cp.dcqHigh; result.dcqLow = cp.dcqLow; return result; } static CX9261AConfiguration convertToCxx(const CX9261A_CX9261AConfiguration& config) { CX9261AConfiguration result; result.tempComp = convertToCxx(config.tempComp); result.agc = convertToCxx(config.agc); result.interface = convertToCxx(config.interface); result.clock = convertToCxx(config.clock); result.pllSource = convertToCxx(config.pllSource); result.calib = convertToCxx(config.calib); result.pllFreq = convertToCxx(config.pllFreq); result.txNco = convertToCxx(config.txNco); result.rxNco = convertToCxx(config.rxNco); result.rx1Config = convertToCxx(config.rx1Config); result.rx2Config = convertToCxx(config.rx2Config); result.rx3Config = convertToCxx(config.rx3Config); result.tx1Config = convertToCxx(config.tx1Config); result.tx2Config = convertToCxx(config.tx2Config); result.rxFilters = convertToCxx(config.rxFilters); result.txFilters = convertToCxx(config.txFilters); result.powerManagement = convertToCxx(config.powerManagement); if(MAX_NUM_FIR < config.numRxFIR) { LOGGING("Rx FIR滤波器系数阶数超出限制 MAX_MULTI_POINTS"); exit(-1); } if(MAX_NUM_FIR < config.numTxFIR) { LOGGING("Rx FIR滤波器系数阶数超出限制 MAX_MULTI_POINTS"); exit(-1); } result.rxFIRCoe.resize(config.numRxFIR); result.txFIRCoe.resize(config.numTxFIR); std::memcpy(result.rxFIRCoe.data(), config.rxFIRCoe, config.numRxFIR); std::memcpy(result.txFIRCoe.data(), config.txFIRCoe, config.numTxFIR); return result; } DEFINE_SIMPLE_C_WRAPPER(initialChip, void) DEFINE_SIMPLE_C_WRAPPER(initialBBPLL, void) DEFINE_SIMPLE_C_WRAPPER(initialPLL1, void) DEFINE_SIMPLE_C_WRAPPER(initialPLL2, void) DEFINE_SIMPLE_C_WRAPPER(initialPLL3, void) DEFINE_SIMPLE_C_WRAPPER(initialPLL4, void) DEFINE_SIMPLE_C_WRAPPER(initialPLL5, void) DEFINE_SIMPLE_C_WRAPPER(configFlashCalib, void) DEFINE_SIMPLE_C_WRAPPER(afcBBPll, bool) DEFINE_SIMPLE_C_WRAPPER(afcPll1, bool) DEFINE_SIMPLE_C_WRAPPER(afcPll2, bool) DEFINE_SIMPLE_C_WRAPPER(afcPll3, bool) DEFINE_SIMPLE_C_WRAPPER(afcPll4, bool) DEFINE_SIMPLE_C_WRAPPER(afcPll5, bool) DEFINE_SIMPLE_C_WRAPPER(waitRxTSTFinished, bool) DEFINE_C_WRAPPER_ONE_PASS(configAGCMode, int, void) DEFINE_C_WRAPPER_ONE_PASS(configRISCV, bool, void) DEFINE_C_WRAPPER_ONE_PASS(configADCCalib, double, void) DEFINE_C_WRAPPER_ONE_PASS(configDcTrackingLength, int, void) DEFINE_C_WRAPPER_ONE_PASS(configDcHighPassFactor, int, void) DEFINE_C_WRAPPER_ONE_PASS(configTxFIR, int, void) DEFINE_C_WRAPPER_ONE_PASS(configTxHBF1, int, void) DEFINE_C_WRAPPER_ONE_PASS(configTxHBF2, int, void) DEFINE_C_WRAPPER_ONE_PASS(configTxHBF3, int, void) DEFINE_C_WRAPPER_ONE_PASS(configTxCIC, int, void) DEFINE_C_WRAPPER_ONE_PASS(configTxBIST, int, void) DEFINE_C_WRAPPER_ONE_PASS(configRxFIR, int, void) DEFINE_C_WRAPPER_ONE_PASS(configRxHBF1, int, void) DEFINE_C_WRAPPER_ONE_PASS(configRxHBF2, int, void) DEFINE_C_WRAPPER_ONE_PASS(configRxHBF3, int, void) DEFINE_C_WRAPPER_ONE_PASS(configRxCIC, int, void) DEFINE_C_WRAPPER_ONE_PASS(configRxMixer, int, void) DEFINE_C_WRAPPER_TWO_PASS(txBisectionQecCalib, double, double, void); DEFINE_C_WRAPPER_TWO_PASS(txBisectionDcCalib, double, double, void) DEFINE_C_WRAPPER_TWO_PASS(configTxNcoFreq, double, double, void); DEFINE_C_WRAPPER_TWO_PASS(configRxNcoFreq, double, double, void); DEFINE_C_WRAPPER_TWO_PASS(configRefDoubler, double, double, void); DEFINE_C_WRAPPER_ONE_PTR_CONVERT(initialPowerConfig, CX9261AConfiguration, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configBBPLL, CX9261AConfiguration, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configAGCPDT, AGCPDT, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configAGCLMT, AGCLMT, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configAGCDIG, AGCDIG, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configAGC, AGC, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(preparePowerForRxCalib, PllSource, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configDcCalib, Calib, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configCalibMethod, Calib, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(preparePowerForTxCalib, PllSource, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(preparePllForTxCalib, CX9261AConfiguration, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(txCalib, CX9261AConfiguration, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configQecCalib, CX9261AConfiguration, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configInterface, Interface, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configPllSource, PllSource, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configTxFilters, Filters, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configRxFilters, Filters, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT(configFPGA, Interface, void) DEFINE_C_WRAPPER_ONE_CONVERT(configTemperatureCompensation, TemperatureComp, void) DEFINE_C_WRAPPER_ONE_CONVERT(rxTSTCalib, RxChannel, void) DEFINE_C_WRAPPER_ONE_CONVERT(configRxNcoMode, NCOMode, void) DEFINE_C_WRAPPER_ONE_CONVERT(configRxNcoMS, NCOMode, void) DEFINE_C_WRAPPER_ONE_CONVERT(configPowerMode, PowerMode, void) DEFINE_C_WRAPPER_ONE_CONVERT(initialRxChannel, RxChannel, void) DEFINE_C_WRAPPER_ONE_CONVERT(initialTxChannel, TxChannel, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_CONVERT(preparePllForRxCalib, CX9261AConfiguration, RxChannel, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_CONVERT(txTSTCalib, CX9261AConfiguration, TxChannel, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_CONVERT(rxCalib, CX9261AConfiguration, RxChannel, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_CONVERT(configPowerPins, Power, PowerMode, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_CONVERT(configRxChannel, RxConfig, RxChannel, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_CONVERT(configTxChannel, TxConfig, TxChannel, void) DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_PASS(configTxNco, TxNCO, double, void); DEFINE_C_WRAPPER_ONE_PTR_CONVERT_ONE_PASS(configRxNco, RxNCO, double, void); DEFINE_C_WRAPPER_ONE_PASS_ONE_PTR_CONVERT(configPll1, double, Clock, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_PTR_CONVERT(configPll2, double, Clock, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_PTR_CONVERT(configPll3, double, Clock, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_PTR_CONVERT(configPll4, double, Clock, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_PTR_CONVERT(configPll5, double, Clock, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_CONVERT(rxDelayCalib, double, RxChannel, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_CONVERT(configRxBandwidth, double, RxChannel, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_CONVERT(configRxTIA, int, RxChannel, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_CONVERT(configTxBandwidth, int, TxChannel, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_CONVERT(configTxMixer, int, TxChannel, void) DEFINE_C_WRAPPER_ONE_PASS_ONE_CONVERT(configTxChannelFrequency, double, TxChannel, void) DEFINE_C_WRAPPER_ONE_PASS_TWO_CONVERT(saveRxCalibPredis, unsigned char, RxChannel, LoSource, void) DEFINE_C_WRAPPER_ONE_PASS_TWO_CONVERT(loadRxCalibPredis, unsigned char, RxChannel, LoSource, void) DEFINE_C_WRAPPER_ONE_PASS_TWO_CONVERT(saveTxCalibPredis, unsigned char, TxChannel, LoSource, void) DEFINE_C_WRAPPER_ONE_PASS_TWO_CONVERT(loadTxCalibPredis, unsigned char, TxChannel, LoSource, void) void CX9261A_beforeQecState(QecStatePair* buff, size_t *len) { std::map state = beforeQecState(); *len = 0; for (const auto&[first, second]: state) { buff[*len].first = first; buff[*len].second = second; (*len)++; } } void CX9261A_restoreQecState(QecStatePair* buff, size_t len) { std::map state; for (std::size_t i = 0; i < len; ++i) { state[buff[i].first] = buff[i].second; } restoreQecState(state); } void CX9261A_configRxMultiPointsQec(const CX9261A_CX9261AConfiguration *config, CX9261A_RxChannel chan, const double *points, size_t len) { std::vector points_vec(points, points+len); configRxMultiPointsQec(convertToCxx(*config), points_vec, convertToCxx(chan)); } void CX9261A_configTxMultiPointsQec(const CX9261A_CX9261AConfiguration *config, const double *points, size_t len) { std::vector points_vec(points, points+len); configTxMultiPointsQec(convertToCxx(*config), points_vec); } void CX9261A_configRxFIRCoe(const double *coe, size_t len) { std::vector coe_vec(coe, coe+len); configRxFIRCoe(coe_vec); } void CX9261A_configTxFIRCoe(const double *coe, size_t len) { std::vector coe_vec(coe, coe+len); configTxFIRCoe(coe_vec); } CX9261A_CalibPredis CX9261A_readRxCalibPredis(CX9261A_RxChannel chan) { return convertToC(readRxCalibPredis(convertToCxx(chan))); } CX9261A_CalibPredis CX9261A_readTxCalibPredis(CX9261A_TxChannel chan) { return convertToC(readTxCalibPredis(convertToCxx(chan))); } static CX9261A_LoggingFunc loggingFunc = NULL; static CX9261A_WriteSpiFunc writeSpiFunc = NULL; static CX9261A_ReadSpiFunc readSpiFunc = NULL; static CX9261A_PauseFunc pauseFunc = NULL; static CX9261A_SetPinFunc setPinFunc = NULL; // 设置函数指针 void CX9261A_setLoggingFunc(CX9261A_LoggingFunc func) { loggingFunc = func; } void CX9261A_setWriteSpiFunc(CX9261A_WriteSpiFunc func) { writeSpiFunc = func; } void CX9261A_setReadSpiFunc(CX9261A_ReadSpiFunc func) { readSpiFunc = func; } void CX9261A_setPauseFunc(CX9261A_PauseFunc func) { pauseFunc = func; } void CX9261A_setSetPinFunc(CX9261A_SetPinFunc func) { setPinFunc = func; } #ifdef USE_LOGGING void CX9261A::logging(const std::string& msg) { if(loggingFunc == NULL) { exit(-1); } return loggingFunc(msg.c_str()); } #endif void CX9261A::writeSpi(int address, int value) { if(writeSpiFunc == NULL) { exit(-1); } return writeSpiFunc(address, value); } int CX9261A::readSpi(int address) { if(readSpiFunc == NULL) { exit(-1); } return readSpiFunc(address); } void CX9261A::pause(double ms) { if(pauseFunc == NULL) { exit(-1); } return pauseFunc(ms); } void CX9261A::setPin(int pin, int value) { if(setPinFunc == NULL) { exit(-1); } return setPinFunc(pin, value); }