www.pudn.com > qtdso-0.3.1.rar > pcs64i.cpp
//====================================================================== // File: pcs64i.cpp // Author: Matthias Toussaint // Created: Mon Jun 10 17:23:31 CEST 2002 //---------------------------------------------------------------------- // Permission to use, copy, modify, and distribute this software and its // documentation for any purpose and without fee is hereby granted, // provided that below copyright notice appear in all copies and that // both that copyright notice and this permission notice appear in // supporting documentation. // // This file is provided AS IS with no warranties of any kind. The // author shall have no liability with respect to the infringement of // copyrights, trade secrets or any patents by this file or any part // thereof. In no event will the author be liable for any lost revenue // or profits or other special, indirect and consequential damages. //---------------------------------------------------------------------- // (c) 2000-2002 Matthias Toussaint //====================================================================== #include#include #include #include #include #include #include Pcs64i::Pcs64i() : Dso( Dso::PCS64i, 8 ) { m_numSamples = 4096; m_preTriggerSize = 1024; m_outBuffer[0] = new unsigned [m_numSamples]; m_outBuffer[1] = new unsigned [m_numSamples]; m_buffer[0] = new unsigned [m_numSamples]; m_buffer[1] = new unsigned [m_numSamples]; int ports = ieee1284_find_ports( &m_list, 0 ); if (E1284_OK == ports) { if (0 == m_list.portc) { std::cerr << "Couldn't find ports" << std::endl; abort(); } else { std::cerr << "find ports: " << m_list.portc << " Using first" << std::endl; std::cerr << "name: " << m_list.portv[0]->name << std::endl; std::cerr << "device: " << m_list.portv[0]->filename << std::endl; m_port = m_list.portv[0]; } } else { std::cerr << "ports fucked up!" << std::endl; abort(); } setTimeBase( Dso::TB1ms ); setVoltsDiv( 0, Dso::VD5v ); setVoltsDiv( 1, Dso::VD5v ); setTriggerEnabled( false ); setTriggerChannel( 0 ); setTriggerRaising( true ); setTriggerLevel( 128 ); m_channelEnable[0] = true; m_channelEnable[1] = true; m_defaultStep = -5; calibrate(); connectToHardware(); } Pcs64i::~Pcs64i() { ieee1284_release( m_port ); ieee1284_free_ports( &m_list ); } bool Pcs64i::hasTimeBase( Dso::TimeBase timeBase ) const { return (timeBase >= Dso::TB100ms && timeBase <= Dso::TB100ns); } bool Pcs64i::hasVoltsDiv( Dso::VoltsDiv voltsDiv ) const { return (voltsDiv >= Dso::VD5v && voltsDiv <= Dso::VD10mv); } void Pcs64i::setChannelEnable( int channel, bool on ) { m_channelEnable[channel] = on; } void Pcs64i::init() { lockParam(); setLatchData( LATCH_TIMEBASE, m_timeBaseByte ); setLatchData( LATCH_VOLTS_DIV, m_voltsDivByte[0] | m_voltsDivByte[1] ); setLatchData( LATCH_TRIGGER, m_triggerByte ); unlockParam(); } void Pcs64i::reset() { setLatchData( LATCH_RESET, 0 ); } void Pcs64i::run() { //while (1) { readSampledData(); // synchronize with reading from widget // lock(); memcpy( m_outBuffer[0], m_buffer[0], 4096*sizeof(unsigned) ); memcpy( m_outBuffer[1], m_buffer[1], 4096*sizeof(unsigned) ); m_outTriggerOffset = m_triggerOffset; m_hasNewData = true; m_triggerOk = true; unlock(); } //exit(); } void Pcs64i::readSampledData() { if (m_equivalentSampling) { unsigned buffer0[4096]; unsigned buffer1[4096]; setTriggerDelay( false ); init(); reset(); readData(); // copy even samples // /*for (int i=0; i<2048; ++i) { buffer0[2*i+1] = m_buffer[0][i+2+512]; buffer1[2*i+1] = m_buffer[1][i+2+512]; }*/ for (int i=0; i<4096; ++i) { buffer0[i] = m_buffer[0][i]; } // do it again with delay switched on // setTriggerDelay( true ); init(); reset(); if (readData()) { // copy even samples // /*for (int i=0; i<2048; ++i) { buffer0[2*i] = m_buffer[0][i+512]; buffer1[2*i] = m_buffer[1][i+512]; }*/ for (int i=0; i<4096; ++i) { m_buffer[1][i] = m_buffer[0][i]; m_buffer[0][i] = buffer0[i]; } // copy back // //memcpy( m_buffer[0], buffer0, 4096*sizeof(unsigned) ); //memcpy( m_buffer[1], buffer1, 4096*sizeof(unsigned) ); } } else { setTriggerDelay( false ); init(); reset(); readData(); int level = triggerLevel(); m_triggerOffset = 0; int tc = triggerChannel(); //std::cerr << "LEVEL=" << level << " CHANNEL=" << tc << std::endl; std::cerr << "step=" << m_step << std::endl; // interpolating only // Assumption: Trigger is too late. Look back to find the offset // starting at pretrigger index if (m_step > 0) { if (triggerRaising()) { for (int i=1024; i>800; --i) { int delta = m_buffer[tc][i]-m_buffer[tc][i-1]; if (delta > 0 && m_buffer[tc][i] > level && m_buffer[tc][i-1] < level) { if (i <= 800) { std::cerr << "FUCKUP: " << i-1024 << std::endl; sleep(2); } m_triggerOffset = m_step*(i-1024); //std::cerr << "off=" << m_triggerOffset; float fac = (float)(level-m_buffer[tc][i-1]) / (float)delta; int dx = (int)qRound((float)m_step * fac); m_triggerOffset += dx; //std::cerr << " delta=" << delta << " dx=" << dx << " fac=" << fac // << " step=" << m_step << std::endl; break; } } } else { for (int i=1024; i>800; --i) { int delta = m_buffer[tc][i]-m_buffer[tc][i-1]; if (delta < 0 && m_buffer[tc][i] < level && m_buffer[tc][i-1] > level) { if (i <= 800) { std::cerr << "FUCKUP: " << i-1024 << std::endl; sleep(2); } m_triggerOffset = m_step*(i-1023); std::cerr << "off=" << m_triggerOffset; float fac = (float)(m_buffer[tc][i-1]-level) / (float)delta; int dx = (int)qRound((float)m_step * fac); m_triggerOffset += dx; std::cerr << " delta=" << delta << " dx=" << dx << " fac=" << fac << " step=" << m_step << std::endl; break; } } } } } } bool Pcs64i::readData() { struct timeval timeout; // juice to the optocoupler before reading // ieee1284_write_data( m_port, 0xf8 ); // timeout is time needed for sampling + 0.5s // unsigned long usecs = (unsigned long)((4096. / m_samplingFrequency) * 1000000. + 500000.); unsigned long secs = usecs / 1000000L; usecs %= 1000000L; timeout.tv_sec = secs; timeout.tv_usec = usecs; if (E1284_TIMEDOUT != ieee1284_wait_status( m_port, 0x80, 0, &timeout )) // if not timeout { const int lengthPlus = m_acqOffset+m_acqLength; // forewind (writing as fast as we can seems no problem) // for (int i=0; i > 3) & 0x0f; } if (m_channelEnable[1]) { ieee1284_write_data( m_port, 0xfd ); // 11111101 ieee1284_write_data( m_port, 0xfd ); // 11111101 ieee1284_read_status( m_port ); m_buffer[1][i] = (ieee1284_read_status( m_port ) << 1) & 0xf0; ieee1284_write_data( m_port, 0xfc ); // 11111100 ieee1284_write_data( m_port, 0xfc ); // 11111100 ieee1284_read_status( m_port ); m_buffer[1][i] |= (ieee1284_read_status( m_port ) >> 3) & 0x0f; } ieee1284_write_data( m_port, 0xf8 ); // 11111000 ieee1284_write_data( m_port, 0xf8 ); // 11111000 } // go to the end // (It's my impression that the PCS64i gives more stable // results if we forewind to the end. Maybe a bug in QtDSO // or a proerty of the scope) for (int i=lengthPlus; i