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.

Committer:
YSI
Date:
Wed Dec 02 15:48:45 2020 +0000
Revision:
5:b5e68cd91f09
Parent:
4:b873a2fda102
add split start and stop count

Who changed what in which revision?

UserRevisionLine numberNew contents of line
YSI 0:d3c997729db1 1 /** Mbed Library Clock Counter
YSI 0:d3c997729db1 2 * Hardware pulse counter with TIMER2 (CAP2.0 or CAP2.1) on Mbed LPC1768
YSI 0:d3c997729db1 3 *
YSI 1:bdbac277828a 4 * Counts signal transitions on p30(CAP2.0) or p29(CAP2.1) for LPC1768 target.
YSI 0:d3c997729db1 5 * Can detecte rising, falling or both signal edge.
YSI 1:bdbac277828a 6 * Return the signal edge count during a period in seconds.
YSI 1:bdbac277828a 7 * In theory (Shannon's theorem) input signal frequency can up to 48 MHz with 96 MHz CCLK.
YSI 1:bdbac277828a 8 * But only tested with frequencys up to 20 MHz and it work.
YSI 0:d3c997729db1 9 *
YSI 0:d3c997729db1 10 * Example :
YSI 0:d3c997729db1 11 * @code
YSI 0:d3c997729db1 12 * #include "mbed.h"
YSI 0:d3c997729db1 13 * #include "lib_ClockCounter.h"
YSI 0:d3c997729db1 14 *
YSI 0:d3c997729db1 15 * Serial pc(USBTX, USBRX);
YSI 0:d3c997729db1 16 * ClockCounter Frequency;
YSI 0:d3c997729db1 17 *
YSI 0:d3c997729db1 18 * int main()
YSI 0:d3c997729db1 19 * {
YSI 0:d3c997729db1 20 * while(1) pc.printf("Frequency = %d Hz\r\n", Frequency.getCount());
YSI 0:d3c997729db1 21 * }
YSI 0:d3c997729db1 22 * @endcode
YSI 0:d3c997729db1 23 */
YSI 0:d3c997729db1 24
YSI 0:d3c997729db1 25 #include "lib_ClockCounter.h"
YSI 5:b5e68cd91f09 26 #include <cstdint>
YSI 0:d3c997729db1 27
YSI 0:d3c997729db1 28 ClockCounter::ClockCounter(PinName PIN_CAP2, edgeDetection EDGE)
YSI 0:d3c997729db1 29 {
YSI 5:b5e68cd91f09 30 _count = 0;
YSI 5:b5e68cd91f09 31 _selectPin = NC;
YSI 0:d3c997729db1 32 switch(PIN_CAP2)
YSI 0:d3c997729db1 33 {
YSI 0:d3c997729db1 34 case p30: case p29:
YSI 0:d3c997729db1 35 // PCONP => Power Mode Control register
YSI 0:d3c997729db1 36 LPC_SC->PCONP |= (0x1<<22); // Bit(22) 1 => Timer2 power on
YSI 0:d3c997729db1 37 // PCLKSEL1 => Peripheral Clock Selection register 1
YSI 0:d3c997729db1 38 LPC_SC->PCLKSEL1 |= (0x1<<12); // Bits(13,12) 01 => PCLK_TIMER2 = CCLK(96 MHz)
YSI 0:d3c997729db1 39 // TCR => Timer Control Register
YSI 0:d3c997729db1 40 LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
YSI 0:d3c997729db1 41 // PINSEL0 => Pin Function Select register 0
YSI 0:d3c997729db1 42 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)
YSI 0:d3c997729db1 43 // CTCR => Count Control Register
YSI 0:d3c997729db1 44 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
YSI 0:d3c997729db1 45 // CCR => Capture Control Register
YSI 0:d3c997729db1 46 LPC_TIM2->CCR = 0x0; // Bits(5,4,3,2,1,0) 000000 => capture and interrupt on event disabled
YSI 0:d3c997729db1 47 break;
YSI 4:b873a2fda102 48 default:
YSI 4:b873a2fda102 49 break;
YSI 0:d3c997729db1 50 }
YSI 0:d3c997729db1 51 }
YSI 0:d3c997729db1 52
YSI 5:b5e68cd91f09 53 void ClockCounter::setPin(PinName PIN_CAP2, edgeDetection EDGE)
YSI 5:b5e68cd91f09 54 {
YSI 5:b5e68cd91f09 55 _selectPin = PIN_CAP2;
YSI 5:b5e68cd91f09 56 switch(PIN_CAP2)
YSI 5:b5e68cd91f09 57 {
YSI 5:b5e68cd91f09 58 case p30: case p29:
YSI 5:b5e68cd91f09 59 // PCONP => Power Mode Control register
YSI 5:b5e68cd91f09 60 LPC_SC->PCONP |= (0x1<<22); // Bit(22) 1 => Timer2 power on
YSI 5:b5e68cd91f09 61 // PCLKSEL1 => Peripheral Clock Selection register 1
YSI 5:b5e68cd91f09 62 LPC_SC->PCLKSEL1 |= (0x1<<12); // Bits(13,12) 01 => PCLK_TIMER2 = CCLK(96 MHz)
YSI 5:b5e68cd91f09 63 // TCR => Timer Control Register
YSI 5:b5e68cd91f09 64 LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
YSI 5:b5e68cd91f09 65 // PINSEL0 => Pin Function Select register 0
YSI 5:b5e68cd91f09 66 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)
YSI 5:b5e68cd91f09 67 // CTCR => Count Control Register
YSI 5:b5e68cd91f09 68 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
YSI 5:b5e68cd91f09 69 // CCR => Capture Control Register
YSI 5:b5e68cd91f09 70 LPC_TIM2->CCR = 0x0; // Bits(5,4,3,2,1,0) 000000 => capture and interrupt on event disabled
YSI 5:b5e68cd91f09 71 break;
YSI 5:b5e68cd91f09 72 default:
YSI 5:b5e68cd91f09 73 break;
YSI 5:b5e68cd91f09 74 }
YSI 5:b5e68cd91f09 75 }
YSI 5:b5e68cd91f09 76
YSI 5:b5e68cd91f09 77 void ClockCounter::startCount(void)
YSI 5:b5e68cd91f09 78 {
YSI 5:b5e68cd91f09 79 // TCR => Timer Control Register
YSI 5:b5e68cd91f09 80 LPC_TIM2->TCR = 0x2; // Bits(1,0) 10 => Timer2 count reset
YSI 5:b5e68cd91f09 81 LPC_TIM2->TCR = 0x1; // Bits(1,0) 01 => Timer2 enabled
YSI 5:b5e68cd91f09 82 }
YSI 5:b5e68cd91f09 83
YSI 5:b5e68cd91f09 84 int ClockCounter::stopCount(void)
YSI 5:b5e68cd91f09 85 {
YSI 5:b5e68cd91f09 86 LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
YSI 5:b5e68cd91f09 87 uint32_t TC = LPC_TIM2->TC; // TC => Timer Counter
YSI 5:b5e68cd91f09 88 _selectPin = NC;
YSI 5:b5e68cd91f09 89 return TC;
YSI 5:b5e68cd91f09 90 }
YSI 5:b5e68cd91f09 91
YSI 3:20dd01b1a1fd 92 int ClockCounter::getCount(int period)
YSI 0:d3c997729db1 93 {
YSI 0:d3c997729db1 94 // TCR => Timer Control Register
YSI 0:d3c997729db1 95 LPC_TIM2->TCR = 0x2; // Bits(1,0) 10 => Timer2 count reset
YSI 0:d3c997729db1 96 LPC_TIM2->TCR = 0x1; // Bits(1,0) 01 => Timer2 enabled
YSI 3:20dd01b1a1fd 97 wait_us(period);
YSI 0:d3c997729db1 98 LPC_TIM2->TCR = 0x0; // Bits(1,0) 00 => Timer2 disabled
YSI 0:d3c997729db1 99 return LPC_TIM2->TC; // TC => Timer Counter
YSI 5:b5e68cd91f09 100 }
YSI 5:b5e68cd91f09 101
YSI 5:b5e68cd91f09 102 PinName ClockCounter::getPin(void)
YSI 5:b5e68cd91f09 103 {
YSI 5:b5e68cd91f09 104 return _selectPin;
YSI 0:d3c997729db1 105 }