HRESULT CbDevice::SetClockSource() { if (_UseSoftwareClock) { return EnableSwClocking(); } else { RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"minsamplerate", CComVariant(_minSampleRate))); RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"maxsamplerate", CComVariant(_maxSampleRate))); pSampleRate.SetRange(_minSampleRate,_maxSampleRate); UpdateRateAndSkew(); } return S_OK; }
//////////////////////////////////////// // SetProperty() // // Called when a property is changed from the MATLAB environment. // It gives us a chance to update other properties, do error checking, etc. // ///////////////////////////////////// STDMETHODIMP CetfarduinoAin::SetProperty(long User, VARIANT* NewValue) { if (User) { CLocalProp* pProp = PROP_FROMUSER(User); variant_t* val = (variant_t*) NewValue; // SampleRate property if (User == USER_VAL(pSampleRate)) { double newSampleRate = *val; if (pClockSource == CLOCKSOURCE_SOFTWARE) { return CswClockedDevice::SetProperty(User, NewValue); } // Calculate a sample rate which is compatible with the board CalculateSampleRate(newSampleRate); *val = pSampleRate; } // ClockSource property if (User == USER_VAL(pClockSource)) { if ((long)(*val) == CLOCKSOURCE_SOFTWARE) { // Software clocking chosen // First, change the SampleRate to SW clocked defaults double softwareClockedDefault = 100; // Let's avoid magic values pSampleRate.SetDefaultValue(CComVariant(softwareClockedDefault)); pSampleRate = softwareClockedDefault; pSampleRate.SetRange( CComVariant((double)MIN_SW_SAMPLERATE), CComVariant((double)MAX_SW_SAMPLERATE)); EnableSwClocking(); // SamplesPerTrigger needs to be configured so that 1s of input data is acquired pSamplesPerTrigger->put_DefaultValue(CComVariant(softwareClockedDefault)); pSamplesPerTrigger = softwareClockedDefault; } else { // Internal (HW) clocking chosen // First, change the SampleRate to SW clocked defaults double internalClockDefault = 1000; pSampleRate.SetDefaultValue(CComVariant(internalClockDefault)); pSampleRate = internalClockDefault; pSampleRate.SetRange(m_minBoardSampleRate, m_maxBoardSampleRate); // Za SwClocking ovaj dio uradi CswClockedDevice::EnableSwClocking RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"minsamplerate", CComVariant(m_minBoardSampleRate))); RETURN_HRESULT(_DaqHwInfo->put_MemberValue(L"maxsamplerate", CComVariant(m_maxBoardSampleRate))); // SamplesPerTrigger needs to be configured so that 1s of input data is acquired pSamplesPerTrigger->put_DefaultValue(CComVariant(internalClockDefault)); pSamplesPerTrigger = internalClockDefault; } } } return S_OK; }
///////////////////////////////////////////////////////////////////////////// // Open() // // Function is called by the OpenDevice(), which is in turn called by the engine. // CetfarduinoAin::Open() function's main goals are .. // 1)to initialize the hardware and hardware dependent properties.. // 2)to expose pointers to the engine and the adaptor to each other.. // 3)to process the device ID, which is input by a user in the MATLAB command line. // The call to this function goes through the hierarchical chain: .. //..CetfarduinoAin::Open() -> CswClockedDevice::Open() -> CmwDevice::Open() // CmwDevice::Open() in its turn populates the pointer to the.. //..engine (CmwDevice::_engine), which allows to access all engine interfaces. // Function MUST BE MODIFIED by the adaptor programmer. ////////////////////////////////////////////////////////////////////////////// HRESULT CetfarduinoAin::Open(IUnknown* Interface, long ID) { if (ID < 0) { // Undocumented MATLAB Daq Engine bug! // When Open() returns an error, the reference to the analoginput object is leaked // and never freed! Thereby, all resources this object owns are also leaked since // the destructor is never called. // :TODO: Implement a way to free all resources without the dtor (cannot use RAII for // this object) return CComCoClass<ImwDevice>::Error(CComBSTR("etfarduino: Invalid device ID.")); } RETURN_HRESULT(TBaseObj::Open(Interface)); DeviceId = ID; TCHAR portName[10]; bool registered = service.CheckDeviceRegistered(DeviceId, portName); if (!registered) { char tempMessage[255]; sprintf(tempMessage, "etfarduino: Device %d not found.", DeviceId); return CComCoClass<ImwDevice>::Error(CComBSTR(tempMessage)); } wchar_t idStr[8]; swprintf(idStr, L"%d", ID); RETURN_HRESULT(_DaqHwInfo->put_MemberValue(CComBSTR(L"id"), CComVariant(idStr))); // Fixed device config values. They could be moved to a config file. m_minBoardSampleRate = 4; m_maxBoardSampleRate = 12500; // 80us period _engine->GetBufferingConfig(&m_engineBufferSamples, NULL); // ------------ // SetDaqHwInfo // ------------ wchar_t deviceName[30]; swprintf(deviceName, _T("etfarduino (Device %d)"), DeviceId); RETURN_HRESULT(InitHwInfo( VT_UI2, Bits, MAX_CHANNELS, // maximum number of channels SE_INPUT, // Setting Single Ended input channels Cetfarduinoadapt::ConstructorName, deviceName)); RETURN_HRESULT(SetDaqHwInfo()); //////////////////////////////// Properties /////////////////////////////////// // The following Section sets the Propinfo for the Analog input device // /////////////////////////////////////////////////////////////////////////////// // Attach to the ClockSource property ATTACH_PROP(ClockSource); // The etfarduino must work as both software and internally clocked EnableSwClocking(); pClockSource->AddMappedEnumValue(CLOCKSOURCE_SOFTWARE, TEXT("Software")); pClockSource->AddMappedEnumValue(CLOCKSOURCE_INTERNAL, TEXT("Internal")); pClockSource->put_DefaultValue(CComVariant(CLOCKSOURCE_INTERNAL)); pClockSource = CLOCKSOURCE_INTERNAL; // SampleRate property double defaultSampleRate = 1000; ATTACH_PROP(SampleRate); pSampleRate.SetDefaultValue(CComVariant(defaultSampleRate)); pSampleRate = defaultSampleRate; pSampleRate.SetRange(m_minBoardSampleRate, m_maxBoardSampleRate); RETURN_HRESULT(_DaqHwInfo->put_MemberValue(TEXT("minsamplerate"), CComVariant(m_minBoardSampleRate))); RETURN_HRESULT(_DaqHwInfo->put_MemberValue(TEXT("maxsamplerate"), CComVariant(m_maxBoardSampleRate))); // SamplesPerTrigger property // Needs to be set so that 1s of data is acquired with the default sample rate ATTACH_PROP(SamplesPerTrigger); pSamplesPerTrigger->put_DefaultValue(CComVariant(defaultSampleRate)); pSamplesPerTrigger = defaultSampleRate; // TriggerRepeat property // How many times will the trigger be repeated ATTACH_PROP(TriggerRepeat); // ---------------------------- // Postaviti InputRange default // ---------------------------- CRemoteProp remoteProp; CComVariant var; // Hardcoded input range of [0, 5] [V] double InputRange[2] = {0., 5.}; CreateSafeVector(InputRange, 2, &var); remoteProp.Attach(_EngineChannelList, TEXT("inputrange")); remoteProp->put_DefaultValue(var); remoteProp->put_User(USER_INPUTRANGE); remoteProp.SetRange(InputRange[0], InputRange[1]); remoteProp.Release(); TRemoteProp<long> pInputType; pInputType.Attach(_EnginePropRoot, L"InputType"); pInputType->AddMappedEnumValue(0, L"SingleEnded"); // TODO: May need to add the ChannelSkewMode enumerated property... return S_OK; } // end of Open()