Library to simplify using capture pins on hardware.

Dependents:   bluesync

When I first started experimenting with the notion of capture pins, I had no idea where to begin. Rather than write to registers in every single program, I decided to create a class that'd handle that heavy lifting for me!

Import library

Public Member Functions

TimerCapture (PinName pCapturePin)
Configures registers to use the given pin as a capture pin.
uint32_t getTime ()
Get the time captured by the capture pin's register.

Static Public Member Functions

static void startTimer ()
Starts the TIMER2 timer, and configures it if it's not already configured.
static bool isRunning ()
Checks if the TIMER2 timer is running.
static void stopTimer ()
Stops the TIMER2 timer.
static void resetTimer ()
Resets the TIMER2 timer.

This code uses TIMER2 on the LPC1768. I have no idea if it will work on other hardware, but I hope it helps someone else!

Committer:
dishbreak
Date:
Wed Jun 10 06:21:13 2015 +0000
Revision:
4:3ae9f68bae6a
Parent:
2:7c4ca945bfe1
Tuning tick counter to behave correctly.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dishbreak 0:94cfc6ceec2f 1 #include "TimerCapture.h"
dishbreak 0:94cfc6ceec2f 2
dishbreak 0:94cfc6ceec2f 3 bool TimerCapture::timerStarted = false;
dishbreak 0:94cfc6ceec2f 4
dishbreak 0:94cfc6ceec2f 5 TimerCapture::TimerCapture(PinName pCapturePin) {
dishbreak 0:94cfc6ceec2f 6 uint8_t bitcount_pinselect = 0;
dishbreak 0:94cfc6ceec2f 7 uint8_t bitcount_capture_control = 0;
dishbreak 0:94cfc6ceec2f 8
dishbreak 0:94cfc6ceec2f 9 #if DEBUG
dishbreak 0:94cfc6ceec2f 10 printf("Entering ctor\r\n");
dishbreak 0:94cfc6ceec2f 11 #endif
dishbreak 0:94cfc6ceec2f 12
dishbreak 0:94cfc6ceec2f 13 switch (pCapturePin) {
dishbreak 0:94cfc6ceec2f 14 case p30:
dishbreak 0:94cfc6ceec2f 15 bitcount_pinselect = 8;
dishbreak 0:94cfc6ceec2f 16 bitcount_capture_control = 0;
dishbreak 0:94cfc6ceec2f 17 break;
dishbreak 0:94cfc6ceec2f 18 case p29:
dishbreak 0:94cfc6ceec2f 19 bitcount_pinselect = 10;
dishbreak 0:94cfc6ceec2f 20 bitcount_capture_control = 3;
dishbreak 0:94cfc6ceec2f 21 break;
dishbreak 0:94cfc6ceec2f 22 default:
dishbreak 0:94cfc6ceec2f 23 error("TimerCapture: Invalid pin specified! Pick either p29 (P0.5) or p30 (p0.4).");
dishbreak 0:94cfc6ceec2f 24 break;
dishbreak 0:94cfc6ceec2f 25 }
dishbreak 0:94cfc6ceec2f 26
dishbreak 0:94cfc6ceec2f 27 #if DEBUG
dishbreak 0:94cfc6ceec2f 28 printf("Bitcounts selected: %d (pinselect) %d (capture control)\r\n", bitcount_pinselect, bitcount_capture_control);
dishbreak 0:94cfc6ceec2f 29 #endif
dishbreak 0:94cfc6ceec2f 30
dishbreak 0:94cfc6ceec2f 31 uint32_t bitmask_pinselect = (0x3 << bitcount_pinselect);
dishbreak 0:94cfc6ceec2f 32 mCapturePin = pCapturePin;
dishbreak 0:94cfc6ceec2f 33
dishbreak 0:94cfc6ceec2f 34 // error out if the pin is already configured.
dishbreak 2:7c4ca945bfe1 35 if ((LPC_PINCON->PINSEL0 & bitmask_pinselect) == bitmask_pinselect) {
dishbreak 0:94cfc6ceec2f 36 error("TimerCapture: Pin is already configured!");
dishbreak 0:94cfc6ceec2f 37 }
dishbreak 0:94cfc6ceec2f 38
dishbreak 2:7c4ca945bfe1 39
dishbreak 2:7c4ca945bfe1 40 //check if peripheral has power, else this operation will hang!
dishbreak 2:7c4ca945bfe1 41 if ((LPC_SC->PCONP & (1 << 22)) == 0) {
dishbreak 2:7c4ca945bfe1 42 error("TimerCapture: Attempted to write to timer registers with power off!");
dishbreak 2:7c4ca945bfe1 43 }
dishbreak 2:7c4ca945bfe1 44
dishbreak 0:94cfc6ceec2f 45 #if DEBUG
dishbreak 0:94cfc6ceec2f 46 printf("OK to configure registers\r\n");
dishbreak 0:94cfc6ceec2f 47 #endif
dishbreak 0:94cfc6ceec2f 48
dishbreak 0:94cfc6ceec2f 49 // configure the pin
dishbreak 0:94cfc6ceec2f 50 LPC_PINCON->PINSEL0 |= bitmask_pinselect;
dishbreak 0:94cfc6ceec2f 51
dishbreak 0:94cfc6ceec2f 52 #if DEBUG
dishbreak 0:94cfc6ceec2f 53 printf("Configuring rising edge. Register is %08x\r\n", LPC_TIM2->CCR);
dishbreak 0:94cfc6ceec2f 54 #endif
dishbreak 0:94cfc6ceec2f 55
dishbreak 0:94cfc6ceec2f 56 // store on rising edge of input
dishbreak 0:94cfc6ceec2f 57 LPC_TIM2->CCR |= (1 << bitcount_capture_control);
dishbreak 0:94cfc6ceec2f 58
dishbreak 0:94cfc6ceec2f 59 #if DEBUG
dishbreak 0:94cfc6ceec2f 60 printf("Leaving ctor\r\n");
dishbreak 0:94cfc6ceec2f 61 #endif
dishbreak 0:94cfc6ceec2f 62 }
dishbreak 0:94cfc6ceec2f 63
dishbreak 0:94cfc6ceec2f 64 void TimerCapture::startTimer() {
dishbreak 0:94cfc6ceec2f 65 if (!timerStarted) {
dishbreak 0:94cfc6ceec2f 66 timerStarted = true;
dishbreak 0:94cfc6ceec2f 67
dishbreak 0:94cfc6ceec2f 68 configureTimer();
dishbreak 0:94cfc6ceec2f 69
dishbreak 0:94cfc6ceec2f 70 //start timer
dishbreak 0:94cfc6ceec2f 71 LPC_TIM2->TCR = 1;
dishbreak 0:94cfc6ceec2f 72 }
dishbreak 0:94cfc6ceec2f 73 }
dishbreak 0:94cfc6ceec2f 74
dishbreak 0:94cfc6ceec2f 75 void TimerCapture::stopTimer() {
dishbreak 0:94cfc6ceec2f 76 timerStarted = false;
dishbreak 0:94cfc6ceec2f 77 //stop timer
dishbreak 0:94cfc6ceec2f 78 LPC_TIM2->TCR = 0;
dishbreak 0:94cfc6ceec2f 79 }
dishbreak 0:94cfc6ceec2f 80
dishbreak 0:94cfc6ceec2f 81 bool TimerCapture::isRunning() {
dishbreak 0:94cfc6ceec2f 82 return timerStarted;
dishbreak 0:94cfc6ceec2f 83 }
dishbreak 0:94cfc6ceec2f 84
dishbreak 0:94cfc6ceec2f 85 void TimerCapture::resetTimer() {
dishbreak 0:94cfc6ceec2f 86 //reset timer
dishbreak 0:94cfc6ceec2f 87 LPC_TIM2->TCR = 2;
dishbreak 0:94cfc6ceec2f 88 LPC_TIM2->TCR = 0;
dishbreak 0:94cfc6ceec2f 89 LPC_TIM2->CR0 = 0;
dishbreak 0:94cfc6ceec2f 90 LPC_TIM2->CR1 = 0;
dishbreak 0:94cfc6ceec2f 91 }
dishbreak 0:94cfc6ceec2f 92
dishbreak 0:94cfc6ceec2f 93 uint32_t TimerCapture::getTime() {
dishbreak 0:94cfc6ceec2f 94 uint32_t observedTime = 0;
dishbreak 0:94cfc6ceec2f 95 switch(mCapturePin) {
dishbreak 0:94cfc6ceec2f 96 case p30:
dishbreak 0:94cfc6ceec2f 97 observedTime = LPC_TIM2->CR0;
dishbreak 0:94cfc6ceec2f 98 break;
dishbreak 0:94cfc6ceec2f 99 case p29:
dishbreak 0:94cfc6ceec2f 100 observedTime = LPC_TIM2->CR1;
dishbreak 0:94cfc6ceec2f 101 break;
dishbreak 0:94cfc6ceec2f 102 default:
dishbreak 0:94cfc6ceec2f 103 observedTime = 0;
dishbreak 0:94cfc6ceec2f 104 break;
dishbreak 0:94cfc6ceec2f 105 }
dishbreak 0:94cfc6ceec2f 106
dishbreak 0:94cfc6ceec2f 107 return observedTime;
dishbreak 0:94cfc6ceec2f 108 }
dishbreak 0:94cfc6ceec2f 109
dishbreak 0:94cfc6ceec2f 110 void TimerCapture::configureTimer() {
dishbreak 0:94cfc6ceec2f 111 // Power on Peripheral TIMER2
dishbreak 0:94cfc6ceec2f 112 LPC_SC->PCONP |= (1 << 22);
dishbreak 0:94cfc6ceec2f 113
dishbreak 0:94cfc6ceec2f 114 // Set clock source for TIMER2
dishbreak 0:94cfc6ceec2f 115 uint8_t clockSel = 0x01;
dishbreak 0:94cfc6ceec2f 116 LPC_SC->PCLKSEL1 |= (clockSel << 12);
dishbreak 0:94cfc6ceec2f 117
dishbreak 0:94cfc6ceec2f 118 // Set prescaler counter
dishbreak 4:3ae9f68bae6a 119 LPC_TIM2->PR = SystemCoreClock/1000; //should increment once a milisecond.
dishbreak 0:94cfc6ceec2f 120
dishbreak 0:94cfc6ceec2f 121 }
dishbreak 0:94cfc6ceec2f 122