int acq_SetChannelThreshold(rp_channel_t channel, float voltage) { float gainV; rp_pinState_t gain; ECHECK(acq_GetGainV(channel, &gainV)); ECHECK(acq_GetGain(channel, &gain));; if (fabs(voltage) - fabs(gainV) > FLOAT_EPS) { return RP_EOOR; } rp_calib_params_t calib = calib_GetParams(); int32_t dc_offs = (channel == RP_CH_1 ? calib.fe_ch1_dc_offs : calib.fe_ch2_dc_offs); uint32_t calibScale = calib_GetFrontEndScale(channel, gain); uint32_t cnt = cmn_CnvVToCnt(ADC_BITS, voltage, gainV, gain == RP_HIGH ? false : true, calibScale, dc_offs, 0.0); // We cut high bits of negative numbers cnt = cnt & ((1 << ADC_BITS) - 1); if (channel == RP_CH_1) { return osc_SetThresholdChA(cnt); } else { return osc_SetThresholdChB(cnt); } }
int acq_SetTriggerLevel(float voltage) { if ((last_trig_src == RP_TRIG_SRC_CHA_PE) || (last_trig_src == RP_TRIG_SRC_CHA_NE)) { ECHECK(acq_SetChannelThreshold(RP_CH_1, voltage)); } else if ((last_trig_src == RP_TRIG_SRC_CHB_PE) || (last_trig_src == RP_TRIG_SRC_CHB_NE)) { ECHECK(acq_SetChannelThreshold(RP_CH_2, voltage)); } return RP_OK; }
int acq_GetTriggerHyst(float *voltage) { if ((last_trig_src == RP_TRIG_SRC_CHA_PE) || (last_trig_src == RP_TRIG_SRC_CHA_NE)) { ECHECK(acq_GetChannelThresholdHyst(RP_CH_1, voltage)); } else if ((last_trig_src == RP_TRIG_SRC_CHA_PE) || (last_trig_src == RP_TRIG_SRC_CHA_NE)) { ECHECK(acq_GetChannelThresholdHyst(RP_CH_2, voltage)); } return RP_OK; }
int acq_GetTriggerDelayNs(int64_t* time_ns) { int32_t samples; ECHECK(acq_GetTriggerDelay(&samples)); *time_ns=cnvSmplsToTime(samples); return RP_OK; }
int acq_SetTriggerDelayNs(int64_t time_ns, bool updateMaxValue) { int32_t samples = cnvTimeToSmpls(time_ns); ECHECK(acq_SetTriggerDelay(samples, updateMaxValue)); triggerDelayInNs = true; return RP_OK; }
int acq_GetSamplingRateHz(float* sampling_rate) { float max_rate = 125000000.0f; rp_acq_decimation_t decimation; ECHECK(acq_GetDecimation(&decimation)); switch(decimation){ case RP_DEC_1: *sampling_rate = max_rate / 1; break; case RP_DEC_8: *sampling_rate = max_rate / 8; break; case RP_DEC_64: *sampling_rate = max_rate / 64; break; case RP_DEC_1024: *sampling_rate = max_rate / 1024; break; case RP_DEC_8192: *sampling_rate = max_rate / 8192; break; case RP_DEC_65536: *sampling_rate = max_rate / 65536; break; } return RP_OK; }
int acq_GetSamplingRate(rp_acq_sampling_rate_t* sampling_rate) { rp_acq_decimation_t decimation; ECHECK(acq_GetDecimation(&decimation)); switch (decimation) { case RP_DEC_1: *sampling_rate = RP_SMP_125M; return RP_OK; case RP_DEC_8: *sampling_rate = RP_SMP_15_625M; return RP_OK; case RP_DEC_64: *sampling_rate = RP_SMP_1_953M; return RP_OK; case RP_DEC_1024: *sampling_rate = RP_SMP_122_070K; return RP_OK; case RP_DEC_8192: *sampling_rate = RP_SMP_15_258K; return RP_OK; case RP_DEC_65536: *sampling_rate = RP_SMP_1_907K; return RP_OK; default: return RP_EOOR; } }
int acq_GetDecimationFactor(uint32_t* decimation) { rp_acq_decimation_t decimationVal; ECHECK(acq_GetDecimation(&decimationVal)); switch (decimationVal) { case RP_DEC_1: *decimation = DEC_1; return RP_OK; case RP_DEC_8: *decimation = DEC_8; return RP_OK; case RP_DEC_64: *decimation = DEC_64; return RP_OK; case RP_DEC_1024: *decimation = DEC_1024; return RP_OK; case RP_DEC_8192: *decimation = DEC_8192; return RP_OK; case RP_DEC_65536: *decimation = DEC_65536; return RP_OK; default: return RP_EOOR; } }
int acq_GetDecimation(rp_acq_decimation_t* decimation) { uint32_t decimationVal; ECHECK(osc_GetDecimation(&decimationVal)); if (decimationVal == DEC_1) { *decimation = RP_DEC_1; return RP_OK; } else if (decimationVal == DEC_8) { *decimation = RP_DEC_8; return RP_OK; } else if (decimationVal == DEC_64) { *decimation = RP_DEC_64; return RP_OK; } else if (decimationVal == DEC_1024) { *decimation = RP_DEC_1024; return RP_OK; } else if (decimationVal == DEC_8192) { *decimation = RP_DEC_8192; return RP_OK; } else if (decimationVal == DEC_65536) { *decimation = RP_DEC_65536; return RP_OK; } else { return RP_EOOR; } }
int generate_Init() { // ECHECK(cmn_Init()); ECHECK(cmn_Map(GENERATE_BASE_SIZE, GENERATE_BASE_ADDR, (void **) &generate)); data_chA = (int32_t *) ((char *) generate + (CHA_DATA_OFFSET)); data_chB = (int32_t *) ((char *) generate + (CHB_DATA_OFFSET)); return RP_OK; }
int generate_Release() { ECHECK(cmn_Unmap(GENERATE_BASE_SIZE, (void **) &generate)); // ECHECK(cmn_Release()); data_chA = NULL; data_chB = NULL; return RP_OK; }
/** * @brief Converts ADC samples to time in [ns] * * * @param[in] samples, number of ADC samples * @retval int time, specified in [ns] */ static int64_t cnvSmplsToTime(int32_t samples) { /* Calculate time (including decimation) */ uint32_t decimation; ECHECK(acq_GetDecimationFactor(&decimation)); return (int64_t)samples * ADC_SAMPLE_PERIOD * (int32_t)decimation; }
/** * Use only when write pointer has stopped... */ int acq_GetOldestDataV(rp_channel_t channel, uint32_t* size, float* buffer) { uint32_t pos; ECHECK(acq_GetWritePointer(&pos)); pos++; return acq_GetDataV(channel, pos, size, buffer); }
/** * @brief Converts time in [ns] to ADC samples * * * @param[in] time time, specified in [ns] * @retval int number of ADC samples */ static uint32_t cnvTimeToSmpls(int64_t time_ns) { /* Calculate sampling period (including decimation) */ uint32_t decimation; ECHECK(acq_GetDecimationFactor(&decimation)); int64_t smpl_p = (ADC_SAMPLE_PERIOD * (int64_t)decimation); return (int32_t)round((double)time_ns / smpl_p); }
int acq_SetGain(rp_channel_t channel, rp_pinState_t state) { rp_pinState_t *gain = NULL; if (channel == RP_CH_1) { gain = &gain_ch_a; } else { gain = &gain_ch_b; } // Read old values which are dependent on the gain... rp_pinState_t old_gain; float ch_thr, ch_hyst; old_gain = *gain; ECHECK(acq_GetChannelThreshold(channel, &ch_thr)); ECHECK(acq_GetChannelThresholdHyst(channel, &ch_hyst)); // Now update the gain *gain = state; // And recalculate new values... int status = acq_SetChannelThreshold(channel, ch_thr); if (status == RP_OK) { status = acq_SetChannelThresholdHyst(channel, ch_hyst); } // In case of an error, put old values back and report the error if (status != RP_OK) { *gain = old_gain; acq_SetChannelThreshold(channel, ch_thr); acq_SetChannelThresholdHyst(channel, ch_hyst); } // At the end if everything is ok, update also equalization filters based on the new gain. // Updating eq filters should never fail... else { status = setEqFilters(channel); } return status; }
int acq_GetDataV2(uint32_t pos, uint32_t* size, float* buffer1, float* buffer2) { *size = MIN(*size, ADC_BUFFER_SIZE); float gainV1, gainV2; rp_pinState_t gain1, gain2; ECHECK(acq_GetGainV(RP_CH_1, &gainV1)); ECHECK(acq_GetGain(RP_CH_1, &gain1)); ECHECK(acq_GetGainV(RP_CH_2, &gainV2)); ECHECK(acq_GetGain(RP_CH_2, &gain2)); rp_calib_params_t calib = calib_GetParams(); int32_t dc_offs1 = calib.fe_ch1_dc_offs; uint32_t calibScale1 = calib_GetFrontEndScale(RP_CH_1, gain1); int32_t dc_offs2 = calib.fe_ch2_dc_offs; uint32_t calibScale2 = calib_GetFrontEndScale(RP_CH_2, gain2); const volatile uint32_t* raw_buffer1 = getRawBuffer(RP_CH_1); const volatile uint32_t* raw_buffer2 = getRawBuffer(RP_CH_2); uint32_t cnts1[*size]; uint32_t cnts2[*size]; uint32_t* ptr1 = cnts1; uint32_t* ptr2 = cnts2; for (uint32_t i = 0; i < (*size); ++i) { *ptr1++ = raw_buffer1[pos]; *ptr2++ = raw_buffer2[pos]; pos = (pos + 1) % ADC_BUFFER_SIZE; } ptr1 = cnts1; ptr2 = cnts2; for (uint32_t i = 0; i < (*size); ++i) { *buffer1++ = cmn_CnvCntToV(ADC_BITS, *ptr1++, gainV1, calibScale1, dc_offs1, 0.0); *buffer2++ = cmn_CnvCntToV(ADC_BITS, *ptr2++, gainV2, calibScale2, dc_offs2, 0.0); } return RP_OK; }
int acq_GetLatestDataV(rp_channel_t channel, uint32_t* size, float* buffer) { *size = MIN(*size, ADC_BUFFER_SIZE); uint32_t pos; ECHECK(acq_GetWritePointer(&pos)); pos = (pos - (*size)) % ADC_BUFFER_SIZE; return acq_GetDataV(channel, pos, size, buffer); }
int acq_GetTriggerState(rp_acq_trig_state_t* state) { bool stateB; ECHECK(osc_GetTriggerState(&stateB)); if (stateB) { *state=RP_TRIG_STATE_TRIGGERED; } else{ *state=RP_TRIG_STATE_WAITING; } return RP_OK; }
int acq_GetDataV(rp_channel_t channel, uint32_t pos, uint32_t* size, float* buffer) { *size = MIN(*size, ADC_BUFFER_SIZE); float gainV; rp_pinState_t gain; ECHECK(acq_GetGainV(channel, &gainV)); ECHECK(acq_GetGain(channel, &gain)); rp_calib_params_t calib = calib_GetParams(); int32_t dc_offs = (channel == RP_CH_1 ? calib.fe_ch1_dc_offs : calib.fe_ch2_dc_offs); uint32_t calibScale = calib_GetFrontEndScale(channel, gain); const volatile uint32_t* raw_buffer = getRawBuffer(channel); uint32_t cnts; for (uint32_t i = 0; i < (*size); ++i) { cnts = raw_buffer[(pos + i) % ADC_BUFFER_SIZE]; buffer[i] = cmn_CnvCntToV(ADC_BITS, cnts, gainV, calibScale, dc_offs, 0.0); } return RP_OK; }
int acq_SetTriggerDelay(int32_t decimated_data_num, bool updateMaxValue) { int32_t trig_dly; if(decimated_data_num < -TRIG_DELAY_ZERO_OFFSET){ trig_dly=0; } else{ trig_dly = decimated_data_num + TRIG_DELAY_ZERO_OFFSET; } ECHECK(osc_SetTriggerDelay(trig_dly)); triggerDelayInNs = false; return RP_OK; }
int acq_GetChannelThresholdHyst(rp_channel_t channel, float* voltage) { float gainV; rp_pinState_t gain; uint32_t cnts; if (channel == RP_CH_1) { ECHECK(osc_GetHysteresisChA(&cnts)); } else { ECHECK(osc_GetHysteresisChB(&cnts)); } ECHECK(acq_GetGainV(channel, &gainV)); ECHECK(acq_GetGain(channel, &gain)); rp_calib_params_t calib = calib_GetParams(); int32_t dc_offs = (channel == RP_CH_1 ? calib.fe_ch1_dc_offs : calib.fe_ch2_dc_offs); uint32_t calibScale = calib_GetFrontEndScale(channel, gain); *voltage = cmn_CnvCntToV(ADC_BITS, cnts, gainV, calibScale, dc_offs, 0.0); return RP_OK; }
int acq_SetChannelThresholdHyst(rp_channel_t channel, float voltage) { float gainV; rp_pinState_t gain; ECHECK(acq_GetGainV(channel, &gainV)); ECHECK(acq_GetGain(channel, &gain));; if (fabs(voltage) - fabs(gainV) > FLOAT_EPS) { return RP_EOOR; } rp_calib_params_t calib = calib_GetParams(); int32_t dc_offs = GET_OFFSET(channel, gain, calib); uint32_t calibScale = calib_GetFrontEndScale(channel, gain); uint32_t cnt = cmn_CnvVToCnt(ADC_BITS, voltage, gainV, gain == RP_HIGH ? false : true, calibScale, dc_offs, 0.0); if (channel == RP_CH_1) { return osc_SetHysteresisChA(cnt); } else { return osc_SetHysteresisChB(cnt); } }
int acq_GetLatestDataRaw(rp_channel_t channel, uint32_t* size, int16_t* buffer) { *size = MIN(*size, ADC_BUFFER_SIZE); uint32_t pos; ECHECK(acq_GetWritePointer(&pos)); pos++; if ((*size) > pos) { pos += ADC_BUFFER_SIZE; } pos -= (*size); return acq_GetDataRaw(channel, pos, size, buffer); }
/** * Sets equalization filter with default coefficients per channel * @param channel Channel A or B * @return 0 when successful */ static int setEqFilters(rp_channel_t channel) { rp_pinState_t gain; ECHECK(acq_GetGain(channel, &gain)); // Update equalization filter with default coefficients if (channel == RP_CH_1) { if (gain == RP_HIGH) { return osc_SetEqFiltersChA( GAIN_HI_CHA_FILT_AA, GAIN_HI_CHA_FILT_BB, GAIN_HI_CHA_FILT_KK, GAIN_HI_CHA_FILT_PP); } else { return osc_SetEqFiltersChA( GAIN_LO_CHA_FILT_AA, GAIN_LO_CHA_FILT_BB, GAIN_LO_CHA_FILT_KK, GAIN_LO_CHA_FILT_PP); } } else { if (gain == RP_HIGH) { return osc_SetEqFiltersChB( GAIN_HI_CHB_FILT_AA, GAIN_HI_CHB_FILT_BB, GAIN_HI_CHB_FILT_KK, GAIN_HI_CHB_FILT_PP); } else { return osc_SetEqFiltersChB( GAIN_LO_CHB_FILT_AA, GAIN_LO_CHB_FILT_BB, GAIN_LO_CHB_FILT_KK, GAIN_LO_CHB_FILT_PP); } } }
int acq_SetDecimation(rp_acq_decimation_t decimation) { int64_t time_ns = 0; if (triggerDelayInNs) { ECHECK(acq_GetTriggerDelayNs(&time_ns)); } switch (decimation) { case RP_DEC_1: ECHECK(osc_SetDecimation(DEC_1)); break; case RP_DEC_8: ECHECK(osc_SetDecimation(DEC_8)); break; case RP_DEC_64: ECHECK(osc_SetDecimation(DEC_64)); break; case RP_DEC_1024: ECHECK(osc_SetDecimation(DEC_1024)); break; case RP_DEC_8192: ECHECK(osc_SetDecimation(DEC_8192)); break; case RP_DEC_65536: ECHECK(osc_SetDecimation(DEC_65536)); break; default: return RP_EOOR; } // Now update trigger delay based on new decimation if (triggerDelayInNs) { ECHECK(acq_SetTriggerDelayNs(time_ns, true)); } return RP_OK; }
int acq_GetDataRaw(rp_channel_t channel, uint32_t pos, uint32_t* size, int16_t* buffer) { *size = MIN(*size, ADC_BUFFER_SIZE); uint32_t cnts; const volatile uint32_t* raw_buffer = getRawBuffer(channel); rp_pinState_t gain; ECHECK(acq_GetGain(channel, &gain)); rp_calib_params_t calib = calib_GetParams(); int32_t dc_offs = GET_OFFSET(channel, gain, calib); for (uint32_t i = 0; i < (*size); ++i) { cnts = (raw_buffer[(pos + i) % ADC_BUFFER_SIZE]) & ADC_BITS_MAK; buffer[i] = cmn_CalibCnts(ADC_BITS, cnts, dc_offs); } return RP_OK; }
void icmp6_opt_print(register const u_char *bp, int resid) { register const struct nd_opt_hdr *op; register const struct nd_opt_hdr *opl; /* why there's no struct? */ register const struct nd_opt_prefix_info *opp; register const struct icmp6_opts_redirect *opr; register const struct nd_opt_mtu *opm; register const u_char *ep; int opts_len; #if 0 register const struct ip6_hdr *ip; register const char *str; register const struct ip6_hdr *oip; register const struct udphdr *ouh; register int hlen, dport; char buf[256]; #endif #if 0 #define TCHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) goto trunc #endif #define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return op = (struct nd_opt_hdr *)bp; #if 0 ip = (struct ip6_hdr *)bp2; oip = &dp->icmp6_ip6; str = buf; #endif /* 'ep' points to the end of avaible data. */ ep = snapend; ECHECK(op->nd_opt_len); if (resid <= 0) return; if (op->nd_opt_len == 0) goto trunc; if (bp + (op->nd_opt_len << 3) > ep) goto trunc; switch (op->nd_opt_type) { case ND_OPT_SOURCE_LINKADDR: opl = (struct nd_opt_hdr *)op; #if 1 if ((u_char *)opl + (opl->nd_opt_len << 3) > ep) goto trunc; #else TCHECK((u_char *)opl + (opl->nd_opt_len << 3) - 1); #endif printf("(src lladdr: %s", etheraddr_string((u_char *)(opl + 1))); if (opl->nd_opt_len != 1) printf("!"); printf(")"); icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3), resid - (op->nd_opt_len << 3)); break; case ND_OPT_TARGET_LINKADDR: opl = (struct nd_opt_hdr *)op; #if 1 if ((u_char *)opl + (opl->nd_opt_len << 3) > ep) goto trunc; #else TCHECK((u_char *)opl + (opl->nd_opt_len << 3) - 1); #endif printf("(tgt lladdr: %s", etheraddr_string((u_char *)(opl + 1))); if (opl->nd_opt_len != 1) printf("!"); printf(")"); icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3), resid - (op->nd_opt_len << 3)); break; case ND_OPT_PREFIX_INFORMATION: opp = (struct nd_opt_prefix_info *)op; TCHECK(opp->nd_opt_pi_prefix); printf("(prefix info: "); if (opp->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) printf("L"); if (opp->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO) printf("A"); if (opp->nd_opt_pi_flags_reserved) printf(" "); printf("valid_ltime="); if ((u_int32_t)ntohl(opp->nd_opt_pi_valid_time) == ~0U) printf("infinity"); else { printf("%u", (u_int32_t)ntohl(opp->nd_opt_pi_valid_time)); } printf(", "); printf("preferred_ltime="); if ((u_int32_t)ntohl(opp->nd_opt_pi_preferred_time) == ~0U) printf("infinity"); else { printf("%u", (u_int32_t)ntohl(opp->nd_opt_pi_preferred_time)); } printf(", "); printf("prefix=%s/%d", ip6addr_string(&opp->nd_opt_pi_prefix), opp->nd_opt_pi_prefix_len); if (opp->nd_opt_pi_len != 4) printf("!"); printf(")"); icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3), resid - (op->nd_opt_len << 3)); break; case ND_OPT_REDIRECTED_HEADER: opr = (struct icmp6_opts_redirect *)op; printf("(redirect)"); /* xxx */ icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3), resid - (op->nd_opt_len << 3)); break; case ND_OPT_MTU: opm = (struct nd_opt_mtu *)op; TCHECK(opm->nd_opt_mtu_mtu); printf("(mtu: "); printf("mtu=%u", (u_int32_t)ntohl(opm->nd_opt_mtu_mtu)); if (opm->nd_opt_mtu_len != 1) printf("!"); printf(")"); icmp6_opt_print((const u_char *)op + (op->nd_opt_len << 3), resid - (op->nd_opt_len << 3)); break; default: opts_len = op->nd_opt_len; printf("(unknown opt_type=%d, opt_len=%d)", op->nd_opt_type, opts_len); if (opts_len == 0) opts_len = 1; /* XXX */ icmp6_opt_print((const u_char *)op + (opts_len << 3), resid - (opts_len << 3)); break; } return; trunc: fputs("[ndp opt]", stdout); return; #if 0 #undef TCHECK #endif #undef ECHECK }
/** * Sets default configuration * @return */ int acq_SetDefault() { ECHECK(acq_SetChannelThreshold(RP_CH_1, 0.0)); ECHECK(acq_SetChannelThreshold(RP_CH_2, 0.0)); ECHECK(acq_SetChannelThresholdHyst(RP_CH_1, 0.0)); ECHECK(acq_SetChannelThresholdHyst(RP_CH_2, 0.0)); ECHECK(acq_SetGain(RP_CH_1, RP_LOW)); ECHECK(acq_SetGain(RP_CH_2, RP_LOW)); ECHECK(acq_SetDecimation(RP_DEC_1)); ECHECK(acq_SetSamplingRate(RP_SMP_125M)); ECHECK(acq_SetAveraging(true)); ECHECK(acq_SetTriggerSrc(RP_TRIG_SRC_DISABLED)); ECHECK(acq_SetTriggerDelay(0, false)); ECHECK(acq_SetTriggerDelayNs(0, false)); return RP_OK; }
int acq_Start() { ECHECK(osc_WriteDataIntoMemory(true)); return RP_OK; }
int acq_Reset() { ECHECK(acq_SetDefault()); return osc_ResetWriteStateMachine(); }