Counts signal transitions on p30(CAP2.0) or p29(CAP2.1) for LPC1768 target. Can detecte rising, falling or both signal edge. Return the signal edge count during a period in seconds. In theory (Shannon's theorem) input signal frequency can up to 48 MHz with 96 MHz CCLK. But only tested with frequencys up to 20 MHz and it work.
lib_ClockCounter.cpp
- Committer:
- YSI
- Date:
- 2020-12-02
- Revision:
- 5:b5e68cd91f09
- Parent:
- 4:b873a2fda102
File content as of revision 5:b5e68cd91f09:
/** Mbed Library Clock Counter
* Hardware pulse counter with TIMER2 (CAP2.0 or CAP2.1) on Mbed LPC1768
*
* Counts signal transitions on p30(CAP2.0) or p29(CAP2.1) for LPC1768 target.
* Can detecte rising, falling or both signal edge.
* Return the signal edge count during a period in seconds.
* In theory (Shannon's theorem) input signal frequency can up to 48 MHz with 96 MHz CCLK.
* But only tested with frequencys up to 20 MHz and it work.
*
* Example :
* @code
* #include "mbed.h"
* #include "lib_ClockCounter.h"
*
* Serial pc(USBTX, USBRX);
* ClockCounter Frequency;
*
* int main()
* {
* while(1) pc.printf("Frequency = %d Hz\r\n", Frequency.getCount());
* }
* @endcode
*/
#include "lib_ClockCounter.h"
#include <cstdint>
ClockCounter::ClockCounter(PinName PIN_CAP2, edgeDetection EDGE)
{
_count = 0;
_selectPin = NC;
switch(PIN_CAP2)
{
case p30: case p29:
// PCONP => Power Mode Control register
LPC_SC->PCONP |= (0x1<<22); // Bit(22) 1 => Timer2 power on
// PCLKSEL1 => Peripheral Clock Selection register 1
LPC_SC->PCLKSEL1 |= (0x1<<12); // Bits(13,12) 01 => PCLK_TIMER2 = CCLK(96 MHz)
// TCR => Timer Control Register
LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
// PINSEL0 => Pin Function Select register 0
LPC_PINCON->PINSEL0 |= (0x3<<((PIN_CAP2==p30)?8:10)); // Bits(9,8) 11 => pin function CAP2.0 (p30), Bits(11,10) 11 => pin function CAP2.1 (p29)
// CTCR => Count Control Register
LPC_TIM2->CTCR = ((PIN_CAP2==p30)?0:4)+EDGE; // Bits(3,2) 00 => CAP2.0 (p30 signal is counter clock) or 11 => CAP2.1 (p29 signal is counter clock), Bits(1,0) XX => timer is incremented on edge
// CCR => Capture Control Register
LPC_TIM2->CCR = 0x0; // Bits(5,4,3,2,1,0) 000000 => capture and interrupt on event disabled
break;
default:
break;
}
}
void ClockCounter::setPin(PinName PIN_CAP2, edgeDetection EDGE)
{
_selectPin = PIN_CAP2;
switch(PIN_CAP2)
{
case p30: case p29:
// PCONP => Power Mode Control register
LPC_SC->PCONP |= (0x1<<22); // Bit(22) 1 => Timer2 power on
// PCLKSEL1 => Peripheral Clock Selection register 1
LPC_SC->PCLKSEL1 |= (0x1<<12); // Bits(13,12) 01 => PCLK_TIMER2 = CCLK(96 MHz)
// TCR => Timer Control Register
LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
// PINSEL0 => Pin Function Select register 0
LPC_PINCON->PINSEL0 |= (0x3<<((PIN_CAP2==p30)?8:10)); // Bits(9,8) 11 => pin function CAP2.0 (p30), Bits(11,10) 11 => pin function CAP2.1 (p29)
// CTCR => Count Control Register
LPC_TIM2->CTCR = ((PIN_CAP2==p30)?0:4)+EDGE; // Bits(3,2) 00 => CAP2.0 (p30 signal is counter clock) or 11 => CAP2.1 (p29 signal is counter clock), Bits(1,0) XX => timer is incremented on edge
// CCR => Capture Control Register
LPC_TIM2->CCR = 0x0; // Bits(5,4,3,2,1,0) 000000 => capture and interrupt on event disabled
break;
default:
break;
}
}
void ClockCounter::startCount(void)
{
// TCR => Timer Control Register
LPC_TIM2->TCR = 0x2; // Bits(1,0) 10 => Timer2 count reset
LPC_TIM2->TCR = 0x1; // Bits(1,0) 01 => Timer2 enabled
}
int ClockCounter::stopCount(void)
{
LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
uint32_t TC = LPC_TIM2->TC; // TC => Timer Counter
_selectPin = NC;
return TC;
}
int ClockCounter::getCount(int period)
{
// TCR => Timer Control Register
LPC_TIM2->TCR = 0x2; // Bits(1,0) 10 => Timer2 count reset
LPC_TIM2->TCR = 0x1; // Bits(1,0) 01 => Timer2 enabled
wait_us(period);
LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
return LPC_TIM2->TC; // TC => Timer Counter
}
PinName ClockCounter::getPin(void)
{
return _selectPin;
}
Y SI