Hardware IO control: mirrors, lock in
lockin.cpp
- Committer:
- mbedalvaro
- Date:
- 2011-10-17
- Revision:
- 0:c19dc1d8b225
File content as of revision 0:c19dc1d8b225:
#include "lockin.h" Lockin lockin=Lockin();//pre-instanciation of object lockin with inter-file scope (declared extern in .h file) void catchInterupt(uint32_t value){ lockin.buffer_pos=(lockin.buffer_pos+1)%BUFFER_SIZE; lockin.buffer[lockin.buffer_pos] = (value>>4)&0xFFF; // this is 12 bit precision ADC (0 to 4095) } // PWM generation is configure as double edge // MR0 (Match Register 0) control the frequency // 'pwm2' uses MR1 and MR2 (rising and falling edges) // 'pwm4' uses MR3 and MR4 (rising and falling edges) // 'pwm1' and 'pwm3' cannot be used since they share the same Match Register // for the moment, all PWM pin are set as output: PwmOut pwm1(p26); PwmOut pwm2(p25); //also defined as LOCKIN_LASER_PIN PwmOut pwm3(p24); PwmOut pwm4(p23); //also defined as LOCKIN_REF_PIN PwmOut pwm5(p22); PwmOut pwm6(p21); //Lockin::Lockin(){} void Lockin::init(){ //configure PWM for the laser and the Lockin refFreq = 147; offsetRef = 40; halfRefFreq = refFreq / 2; refFrequency = 653; //init the lock-in frequency at 653 kHz phaseShiftLaser = 0.546; //offset of 54% for the laser signal phaseShiftLockin = 0; //no offset for the lock-in reference initPWM(); //configure ADC: clearBuffer(); adc.startmode(0,0); adc.burst(1); adc.setup(LOCKIN_ADC_PIN, 1); adc.select(LOCKIN_ADC_PIN); adc.interrupt_state(LOCKIN_ADC_PIN, 1); adc.append(LOCKIN_ADC_PIN, catchInterupt); } void Lockin::initPWM(){ float halfPeriod = 0.5 * MBEDFREQUENCY / refFrequency; // half shared periof _currentMR[0] = int(1.0 * MBEDFREQUENCY / refFrequency); //save the current value of MR0 (shared periof) //147 _currentMR[1] = int(phaseShiftLaser * halfPeriod); //save the current value of MR1 //40 _currentMR[2] = int(_currentMR[1] + halfPeriod); //save the current value of MR2 //40+73 _currentMR[3] = int(phaseShiftLockin * halfPeriod); //save the current value of MR1 //0 _currentMR[4] = int(_currentMR[3] + halfPeriod); //save the current value of MR2 //73 // set PWM: LPC_PWM1->TCR = (1 << 1); // Reset counter, disable PWM LPC_SC->PCLKSEL0 &= ~(0x3 << 12); LPC_SC->PCLKSEL0 |= (1 << 12); // Set peripheral clock divider to /1, i.e. system clock LPC_PWM1->PCR |= 0x0014; // Double edge PWM for PWM2,4 LPC_PWM1->MR0 = _currentMR[0]; // Match Register 0 is shared period counter for all PWM1 LPC_PWM1->MR1 = _currentMR[1]; // Match Register 1 is laser rising edge counter LPC_PWM1->MR2 = _currentMR[2]; // Match Register 2 is laser falling edge counter LPC_PWM1->MR3 = _currentMR[3]; // Match Register 3 is lock-in rising edge counter LPC_PWM1->MR4 = _currentMR[4]; // Match Register 4 is lock-in falling edge counter LPC_PWM1->LER |= 1; // Start updating at next period start LPC_PWM1->TCR = (1 << 0) || (1 << 3); // Enable counter and PWM } //change the frequency of the PWM after initPWM() void Lockin::setPWMFrequency(float freq){ refFrequency = freq; _currentMR[0] = int(MBEDFREQUENCY / refFrequency); //save the current value of MR0 LPC_PWM1->MR0 = _currentMR[0]; //update PWM shared period register LPC_PWM1->LER |= 1; //update PWM } //change the phase shift of the sensing laser after initPWM() void Lockin::setLaserPhaseShift(float phaseShift){ phaseShiftLaser = phaseShift; float halfPeriod = 0.5 * MBEDFREQUENCY / refFrequency; _currentMR[1] = int(phaseShiftLaser * halfPeriod); //save the current value of MR1 _currentMR[2] = _currentMR[1] + halfPeriod; //save the current value of MR2 LPC_PWM1->MR1 = _currentMR[1]; //update Laser rising edge match register LPC_PWM1->MR2 = _currentMR[2]; //update Laser faling edge match register } //change the phase shift of the lock-in after initPWM() void Lockin::setLockinPhaseShift(float phaseShift){ phaseShiftLockin = phaseShift; float halfPeriod = 0.5 * MBEDFREQUENCY / refFrequency; _currentMR[3] = int(phaseShiftLockin * halfPeriod); //save the current value of MR1 _currentMR[4] = _currentMR[3] + halfPeriod; //save the current value of MR2 LPC_PWM1->MR3 = _currentMR[3]; //update lock-in rising edge match register LPC_PWM1->MR4 = _currentMR[4]; //update lock-in faling edge match register } void Lockin::setLaserPower(bool power){ if(power){ LPC_PWM1->MR1 = _currentMR[1]; LPC_PWM1->MR2 = _currentMR[2]; LPC_PWM1->LER |= 1; // update PWM at the next period } else{ LPC_PWM1->MR1 = 0; //set rising edge at 0 LPC_PWM1->MR2 = 0; //set falling edge at 0 LPC_PWM1->LER |= 1; // update PWM at the next period } } void Lockin::clearBuffer(){ for(int i=0; i<BUFFER_SIZE; i++){ buffer[i] = 0; } buffer_pos = BUFFER_SIZE; } /* void Lockin::catchInterupt(uint32_t value){ buffer_pos++; buffer_pos%=BUFFER_SIZE; buffer[buffer_pos] = value; } */ float Lockin::getSmoothValue(){ float smoothValue = buffer[0]; for(int i=1; i<BUFFER_SIZE; i++){ smoothValue += buffer[i]; } smoothValue /= BUFFER_SIZE; return smoothValue; } float Lockin::getLastValue(){ return buffer[buffer_pos]; }