Hardware IO control: mirrors, lock in

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?

UserRevisionLine numberNew 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 }