Hardware IO control: mirrors, lock in
lockin.cpp@0:c19dc1d8b225, 2011-10-17 (annotated)
- Committer:
- mbedalvaro
- Date:
- Mon Oct 17 13:23:06 2011 +0000
- Revision:
- 0:c19dc1d8b225
I wonder if perhaps it would be better to avoid a hardwareIO object, and instead have a set of global hardware functions... I think I will do this in the next revisions of this library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbedalvaro | 0:c19dc1d8b225 | 1 | #include "lockin.h" |
mbedalvaro | 0:c19dc1d8b225 | 2 | |
mbedalvaro | 0:c19dc1d8b225 | 3 | Lockin lockin=Lockin();//pre-instanciation of object lockin with inter-file scope (declared extern in .h file) |
mbedalvaro | 0:c19dc1d8b225 | 4 | |
mbedalvaro | 0:c19dc1d8b225 | 5 | void catchInterupt(uint32_t value){ |
mbedalvaro | 0:c19dc1d8b225 | 6 | lockin.buffer_pos=(lockin.buffer_pos+1)%BUFFER_SIZE; |
mbedalvaro | 0:c19dc1d8b225 | 7 | lockin.buffer[lockin.buffer_pos] = (value>>4)&0xFFF; // this is 12 bit precision ADC (0 to 4095) |
mbedalvaro | 0:c19dc1d8b225 | 8 | } |
mbedalvaro | 0:c19dc1d8b225 | 9 | |
mbedalvaro | 0:c19dc1d8b225 | 10 | // PWM generation is configure as double edge |
mbedalvaro | 0:c19dc1d8b225 | 11 | // MR0 (Match Register 0) control the frequency |
mbedalvaro | 0:c19dc1d8b225 | 12 | // 'pwm2' uses MR1 and MR2 (rising and falling edges) |
mbedalvaro | 0:c19dc1d8b225 | 13 | // 'pwm4' uses MR3 and MR4 (rising and falling edges) |
mbedalvaro | 0:c19dc1d8b225 | 14 | // 'pwm1' and 'pwm3' cannot be used since they share the same Match Register |
mbedalvaro | 0:c19dc1d8b225 | 15 | // for the moment, all PWM pin are set as output: |
mbedalvaro | 0:c19dc1d8b225 | 16 | PwmOut pwm1(p26); |
mbedalvaro | 0:c19dc1d8b225 | 17 | PwmOut pwm2(p25); //also defined as LOCKIN_LASER_PIN |
mbedalvaro | 0:c19dc1d8b225 | 18 | PwmOut pwm3(p24); |
mbedalvaro | 0:c19dc1d8b225 | 19 | PwmOut pwm4(p23); //also defined as LOCKIN_REF_PIN |
mbedalvaro | 0:c19dc1d8b225 | 20 | PwmOut pwm5(p22); |
mbedalvaro | 0:c19dc1d8b225 | 21 | PwmOut pwm6(p21); |
mbedalvaro | 0:c19dc1d8b225 | 22 | |
mbedalvaro | 0:c19dc1d8b225 | 23 | //Lockin::Lockin(){} |
mbedalvaro | 0:c19dc1d8b225 | 24 | |
mbedalvaro | 0:c19dc1d8b225 | 25 | void Lockin::init(){ |
mbedalvaro | 0:c19dc1d8b225 | 26 | |
mbedalvaro | 0:c19dc1d8b225 | 27 | //configure PWM for the laser and the Lockin |
mbedalvaro | 0:c19dc1d8b225 | 28 | refFreq = 147; |
mbedalvaro | 0:c19dc1d8b225 | 29 | offsetRef = 40; |
mbedalvaro | 0:c19dc1d8b225 | 30 | halfRefFreq = refFreq / 2; |
mbedalvaro | 0:c19dc1d8b225 | 31 | |
mbedalvaro | 0:c19dc1d8b225 | 32 | refFrequency = 653; //init the lock-in frequency at 653 kHz |
mbedalvaro | 0:c19dc1d8b225 | 33 | phaseShiftLaser = 0.546; //offset of 54% for the laser signal |
mbedalvaro | 0:c19dc1d8b225 | 34 | phaseShiftLockin = 0; //no offset for the lock-in reference |
mbedalvaro | 0:c19dc1d8b225 | 35 | initPWM(); |
mbedalvaro | 0:c19dc1d8b225 | 36 | |
mbedalvaro | 0:c19dc1d8b225 | 37 | //configure ADC: |
mbedalvaro | 0:c19dc1d8b225 | 38 | clearBuffer(); |
mbedalvaro | 0:c19dc1d8b225 | 39 | |
mbedalvaro | 0:c19dc1d8b225 | 40 | adc.startmode(0,0); |
mbedalvaro | 0:c19dc1d8b225 | 41 | adc.burst(1); |
mbedalvaro | 0:c19dc1d8b225 | 42 | adc.setup(LOCKIN_ADC_PIN, 1); |
mbedalvaro | 0:c19dc1d8b225 | 43 | adc.select(LOCKIN_ADC_PIN); |
mbedalvaro | 0:c19dc1d8b225 | 44 | adc.interrupt_state(LOCKIN_ADC_PIN, 1); |
mbedalvaro | 0:c19dc1d8b225 | 45 | adc.append(LOCKIN_ADC_PIN, catchInterupt); |
mbedalvaro | 0:c19dc1d8b225 | 46 | } |
mbedalvaro | 0:c19dc1d8b225 | 47 | |
mbedalvaro | 0:c19dc1d8b225 | 48 | |
mbedalvaro | 0:c19dc1d8b225 | 49 | void Lockin::initPWM(){ |
mbedalvaro | 0:c19dc1d8b225 | 50 | |
mbedalvaro | 0:c19dc1d8b225 | 51 | float halfPeriod = 0.5 * MBEDFREQUENCY / refFrequency; // half shared periof |
mbedalvaro | 0:c19dc1d8b225 | 52 | _currentMR[0] = int(1.0 * MBEDFREQUENCY / refFrequency); //save the current value of MR0 (shared periof) //147 |
mbedalvaro | 0:c19dc1d8b225 | 53 | _currentMR[1] = int(phaseShiftLaser * halfPeriod); //save the current value of MR1 //40 |
mbedalvaro | 0:c19dc1d8b225 | 54 | _currentMR[2] = int(_currentMR[1] + halfPeriod); //save the current value of MR2 //40+73 |
mbedalvaro | 0:c19dc1d8b225 | 55 | _currentMR[3] = int(phaseShiftLockin * halfPeriod); //save the current value of MR1 //0 |
mbedalvaro | 0:c19dc1d8b225 | 56 | _currentMR[4] = int(_currentMR[3] + halfPeriod); //save the current value of MR2 //73 |
mbedalvaro | 0:c19dc1d8b225 | 57 | |
mbedalvaro | 0:c19dc1d8b225 | 58 | |
mbedalvaro | 0:c19dc1d8b225 | 59 | // set PWM: |
mbedalvaro | 0:c19dc1d8b225 | 60 | LPC_PWM1->TCR = (1 << 1); // Reset counter, disable PWM |
mbedalvaro | 0:c19dc1d8b225 | 61 | LPC_SC->PCLKSEL0 &= ~(0x3 << 12); |
mbedalvaro | 0:c19dc1d8b225 | 62 | LPC_SC->PCLKSEL0 |= (1 << 12); // Set peripheral clock divider to /1, i.e. system clock |
mbedalvaro | 0:c19dc1d8b225 | 63 | |
mbedalvaro | 0:c19dc1d8b225 | 64 | LPC_PWM1->PCR |= 0x0014; // Double edge PWM for PWM2,4 |
mbedalvaro | 0:c19dc1d8b225 | 65 | |
mbedalvaro | 0:c19dc1d8b225 | 66 | LPC_PWM1->MR0 = _currentMR[0]; // Match Register 0 is shared period counter for all PWM1 |
mbedalvaro | 0:c19dc1d8b225 | 67 | |
mbedalvaro | 0:c19dc1d8b225 | 68 | LPC_PWM1->MR1 = _currentMR[1]; // Match Register 1 is laser rising edge counter |
mbedalvaro | 0:c19dc1d8b225 | 69 | LPC_PWM1->MR2 = _currentMR[2]; // Match Register 2 is laser falling edge counter |
mbedalvaro | 0:c19dc1d8b225 | 70 | LPC_PWM1->MR3 = _currentMR[3]; // Match Register 3 is lock-in rising edge counter |
mbedalvaro | 0:c19dc1d8b225 | 71 | LPC_PWM1->MR4 = _currentMR[4]; // Match Register 4 is lock-in falling edge counter |
mbedalvaro | 0:c19dc1d8b225 | 72 | |
mbedalvaro | 0:c19dc1d8b225 | 73 | LPC_PWM1->LER |= 1; // Start updating at next period start |
mbedalvaro | 0:c19dc1d8b225 | 74 | LPC_PWM1->TCR = (1 << 0) || (1 << 3); // Enable counter and PWM |
mbedalvaro | 0:c19dc1d8b225 | 75 | } |
mbedalvaro | 0:c19dc1d8b225 | 76 | |
mbedalvaro | 0:c19dc1d8b225 | 77 | //change the frequency of the PWM after initPWM() |
mbedalvaro | 0:c19dc1d8b225 | 78 | void Lockin::setPWMFrequency(float freq){ |
mbedalvaro | 0:c19dc1d8b225 | 79 | refFrequency = freq; |
mbedalvaro | 0:c19dc1d8b225 | 80 | _currentMR[0] = int(MBEDFREQUENCY / refFrequency); //save the current value of MR0 |
mbedalvaro | 0:c19dc1d8b225 | 81 | LPC_PWM1->MR0 = _currentMR[0]; //update PWM shared period register |
mbedalvaro | 0:c19dc1d8b225 | 82 | LPC_PWM1->LER |= 1; //update PWM |
mbedalvaro | 0:c19dc1d8b225 | 83 | } |
mbedalvaro | 0:c19dc1d8b225 | 84 | |
mbedalvaro | 0:c19dc1d8b225 | 85 | //change the phase shift of the sensing laser after initPWM() |
mbedalvaro | 0:c19dc1d8b225 | 86 | void Lockin::setLaserPhaseShift(float phaseShift){ |
mbedalvaro | 0:c19dc1d8b225 | 87 | phaseShiftLaser = phaseShift; |
mbedalvaro | 0:c19dc1d8b225 | 88 | float halfPeriod = 0.5 * MBEDFREQUENCY / refFrequency; |
mbedalvaro | 0:c19dc1d8b225 | 89 | _currentMR[1] = int(phaseShiftLaser * halfPeriod); //save the current value of MR1 |
mbedalvaro | 0:c19dc1d8b225 | 90 | _currentMR[2] = _currentMR[1] + halfPeriod; //save the current value of MR2 |
mbedalvaro | 0:c19dc1d8b225 | 91 | |
mbedalvaro | 0:c19dc1d8b225 | 92 | LPC_PWM1->MR1 = _currentMR[1]; //update Laser rising edge match register |
mbedalvaro | 0:c19dc1d8b225 | 93 | LPC_PWM1->MR2 = _currentMR[2]; //update Laser faling edge match register |
mbedalvaro | 0:c19dc1d8b225 | 94 | } |
mbedalvaro | 0:c19dc1d8b225 | 95 | |
mbedalvaro | 0:c19dc1d8b225 | 96 | //change the phase shift of the lock-in after initPWM() |
mbedalvaro | 0:c19dc1d8b225 | 97 | void Lockin::setLockinPhaseShift(float phaseShift){ |
mbedalvaro | 0:c19dc1d8b225 | 98 | phaseShiftLockin = phaseShift; |
mbedalvaro | 0:c19dc1d8b225 | 99 | float halfPeriod = 0.5 * MBEDFREQUENCY / refFrequency; |
mbedalvaro | 0:c19dc1d8b225 | 100 | _currentMR[3] = int(phaseShiftLockin * halfPeriod); //save the current value of MR1 |
mbedalvaro | 0:c19dc1d8b225 | 101 | _currentMR[4] = _currentMR[3] + halfPeriod; //save the current value of MR2 |
mbedalvaro | 0:c19dc1d8b225 | 102 | |
mbedalvaro | 0:c19dc1d8b225 | 103 | LPC_PWM1->MR3 = _currentMR[3]; //update lock-in rising edge match register |
mbedalvaro | 0:c19dc1d8b225 | 104 | LPC_PWM1->MR4 = _currentMR[4]; //update lock-in faling edge match register |
mbedalvaro | 0:c19dc1d8b225 | 105 | } |
mbedalvaro | 0:c19dc1d8b225 | 106 | |
mbedalvaro | 0:c19dc1d8b225 | 107 | |
mbedalvaro | 0:c19dc1d8b225 | 108 | void Lockin::setLaserPower(bool power){ |
mbedalvaro | 0:c19dc1d8b225 | 109 | if(power){ |
mbedalvaro | 0:c19dc1d8b225 | 110 | LPC_PWM1->MR1 = _currentMR[1]; |
mbedalvaro | 0:c19dc1d8b225 | 111 | LPC_PWM1->MR2 = _currentMR[2]; |
mbedalvaro | 0:c19dc1d8b225 | 112 | LPC_PWM1->LER |= 1; // update PWM at the next period |
mbedalvaro | 0:c19dc1d8b225 | 113 | } |
mbedalvaro | 0:c19dc1d8b225 | 114 | else{ |
mbedalvaro | 0:c19dc1d8b225 | 115 | LPC_PWM1->MR1 = 0; //set rising edge at 0 |
mbedalvaro | 0:c19dc1d8b225 | 116 | LPC_PWM1->MR2 = 0; //set falling edge at 0 |
mbedalvaro | 0:c19dc1d8b225 | 117 | LPC_PWM1->LER |= 1; // update PWM at the next period |
mbedalvaro | 0:c19dc1d8b225 | 118 | } |
mbedalvaro | 0:c19dc1d8b225 | 119 | } |
mbedalvaro | 0:c19dc1d8b225 | 120 | |
mbedalvaro | 0:c19dc1d8b225 | 121 | void Lockin::clearBuffer(){ |
mbedalvaro | 0:c19dc1d8b225 | 122 | for(int i=0; i<BUFFER_SIZE; i++){ |
mbedalvaro | 0:c19dc1d8b225 | 123 | buffer[i] = 0; |
mbedalvaro | 0:c19dc1d8b225 | 124 | } |
mbedalvaro | 0:c19dc1d8b225 | 125 | buffer_pos = BUFFER_SIZE; |
mbedalvaro | 0:c19dc1d8b225 | 126 | } |
mbedalvaro | 0:c19dc1d8b225 | 127 | |
mbedalvaro | 0:c19dc1d8b225 | 128 | /* |
mbedalvaro | 0:c19dc1d8b225 | 129 | void Lockin::catchInterupt(uint32_t value){ |
mbedalvaro | 0:c19dc1d8b225 | 130 | buffer_pos++; |
mbedalvaro | 0:c19dc1d8b225 | 131 | buffer_pos%=BUFFER_SIZE; |
mbedalvaro | 0:c19dc1d8b225 | 132 | buffer[buffer_pos] = value; |
mbedalvaro | 0:c19dc1d8b225 | 133 | } |
mbedalvaro | 0:c19dc1d8b225 | 134 | */ |
mbedalvaro | 0:c19dc1d8b225 | 135 | |
mbedalvaro | 0:c19dc1d8b225 | 136 | float Lockin::getSmoothValue(){ |
mbedalvaro | 0:c19dc1d8b225 | 137 | float smoothValue = buffer[0]; |
mbedalvaro | 0:c19dc1d8b225 | 138 | for(int i=1; i<BUFFER_SIZE; i++){ |
mbedalvaro | 0:c19dc1d8b225 | 139 | smoothValue += buffer[i]; |
mbedalvaro | 0:c19dc1d8b225 | 140 | } |
mbedalvaro | 0:c19dc1d8b225 | 141 | smoothValue /= BUFFER_SIZE; |
mbedalvaro | 0:c19dc1d8b225 | 142 | |
mbedalvaro | 0:c19dc1d8b225 | 143 | return smoothValue; |
mbedalvaro | 0:c19dc1d8b225 | 144 | } |
mbedalvaro | 0:c19dc1d8b225 | 145 | |
mbedalvaro | 0:c19dc1d8b225 | 146 | float Lockin::getLastValue(){ |
mbedalvaro | 0:c19dc1d8b225 | 147 | return buffer[buffer_pos]; |
mbedalvaro | 0:c19dc1d8b225 | 148 | } |