bunt _ / PulseCounter
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PulseCounter.cpp Source File

PulseCounter.cpp

00001 /* Copyright (c) 2012 Christian Buntebarth, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction, 
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or 
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 
00019 #include "mbed.h"
00020 #include "PulseCounter.h"
00021 
00022 PulseCounter *PulseCounter::instance;
00023 
00024 extern int CLOCK_FREQUENCY;
00025 
00026 void PulseCounter::init()
00027 {
00028     instance = this;                    // pointer to instance
00029     
00030     // Power Control for Peripherals Register
00031     LPC_SC->PCONP |= (1<<22);           // Bit 22:          1 = Timer2 power on
00032 
00033     // Pin Function Select Register
00034     LPC_PINCON->PINSEL0 |= (0x3<<8);    // Bits 9/8:      1/1 = pin function CAP2.0 (p30)  
00035     LPC_PINCON->PINSEL0 |= (0x3<<10);   // Bits 11/10:    1/1 = pin function CAP2.1 (p29)     
00036 
00037     // Peripheral Clock Selection Register
00038     LPC_SC->PCLKSEL1 |= (0x1<<12);      // Bits 13/12:    0/1 = CCLK ( 96 MHz ) 
00039     // Prescale Register
00040     LPC_TIM2->PR = 0x0;                 //                  0 = no prescaling
00041 
00042     // Count Control Register
00043     LPC_TIM2->CTCR = 0x5;               // Bits 1/0:      0/1 = timer is incremented on rising edge on clock sample capture pin  
00044                                         // Bits 3/2:      0/1 = clock sample capture pin: CAP2.1 (p29), (p29 signal is counter clock)
00045      
00046     // Capture Control Register 
00047     LPC_TIM2->CCR = 0x5;                // Bits 2/1/0:  1/0/1 = capture on rising edge / generate interrupt on event
00048                                         // Bits 5/4/3:  0/0/0 = don't capture - this is the clock sample capture pin
00049 
00050     // Set custom method to be called on Timer2 interrupt
00051     NVIC_DisableIRQ(TIMER2_IRQn);
00052     NVIC_SetVector(TIMER2_IRQn, (uint32_t)&_triggerInterrupt);
00053     //
00054 
00055     LPC_TIM2->TCR = 0x2;            // Timer2 count reset
00056     LPC_TIM2->TCR = 0x0;            // Timer2 disabled
00057     
00058     _hasFinishedCounting = true;
00059 }
00060 
00061 void PulseCounter::start()
00062 {   
00063     // reset array pointer to first array element
00064     int arrayLength = sizeof(_pulseCountArray)/sizeof(uint32_t);
00065     for(int i = 0; i < arrayLength; i++) {
00066         _pulseCountArray[i] = 0;
00067     }
00068     _arrayPointer = &_pulseCountArray[0];
00069     _triggerCounter = 0;
00070     //
00071         
00072     LPC_TIM2->TCR = 1;              // Timer2 start
00073     NVIC_EnableIRQ(TIMER2_IRQn);    // enable capture interrupt
00074  
00075     _hasFinishedCounting = false;
00076 }
00077 
00078 void PulseCounter::stop()
00079 {
00080     LPC_TIM2->TCR = 0;              // Timer2 stop
00081     NVIC_DisableIRQ(TIMER2_IRQn);   // disable capture interrupt
00082 
00083     _hasFinishedCounting = true;
00084 }
00085 
00086 void PulseCounter::counterArray(uint32_t* counterArray, int counterArrayLength)
00087 {        
00088     int i = 1;
00089     if(_hasFinishedCounting == true) {
00090         while(i <= _pulseCountArrayLength) {
00091             *counterArray = _pulseCountArray[i];
00092             counterArray++;
00093             i++;
00094             if (i > counterArrayLength) {
00095                 // parameter counterArray has less elements than pulseCountArray. Stop copying elements.
00096                 break;
00097             }
00098         }
00099     } else {
00100         // User didn't call stop() before reading pulseCountArray - prevent simultaneous read and write on array. Just return zero array.
00101         while(i <= _pulseCountArrayLength) {
00102             *counterArray = 0;
00103             counterArray++;
00104             i++;
00105             if (i > counterArrayLength) {
00106                 // parameter counterArray has less elements than pulseCountArray. Stop copying elements.
00107                 break;
00108             }
00109         }
00110     }
00111     
00112     // if parameter counterArray has more elements than pulseCountArray. Fill up with zeros.
00113     if(counterArrayLength > _pulseCountArrayLength) {
00114         while(i <= counterArrayLength) {
00115             *counterArray = 0;
00116             counterArray++; 
00117             i++;
00118         }
00119     }
00120 }
00121 
00122 void PulseCounter::_triggerInterrupt()
00123 {        
00124     instance->_arrayPointer++;                  // increment array pointer
00125     wait_us(1);                                     // incrementing pointer needs a little time
00126     *instance->_arrayPointer = LPC_TIM2->CR0;   // store capture time in eventTimeCount-Array 
00127     
00128     LPC_TIM2->TCR = 0x2;            // Timer2 count reset
00129     LPC_TIM2->TCR = 0x0;            // Timer2 disabled
00130     LPC_TIM2->TCR = 0x1;            // Timer2 enabled
00131     
00132     instance->_triggerCounter++; 
00133     if (instance->_triggerCounter > _pulseCountArrayLength) {
00134         instance->_arrayPointer = &instance->_pulseCountArray[0];
00135         instance->_triggerCounter = 0;
00136     }
00137         
00138     LPC_TIM2->IR = 0x10;                            // clear interrupt     
00139 }
00140