Y SI / lib_ClockCounter
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 }