Input Capture with Timer_A
Most of the example code and discussion has been on the output compare feature of Timer_A. This section covers most of what you need to get started with the input capture of Timer_A.
As with output compare, you will need to select an operation mode for the timer. Please review the Modes of Operation page to see all of the possible modes Timer_A can be configured in. Then, refer to Programming with Timer_A to actually program and configure your desired operation mode.
Like with output compare, we have a very convenient struct that we can use to get input capture set up:
typedef struct _Timer_A_CaptureModeConfig
{
uint_fast16_t captureRegister;
uint_fast16_t captureMode;
uint_fast16_t captureInputSelect;
uint_fast16_t synchronizeCaptureSource;
uint_fast8_t captureInterruptEnable;
uint_fast16_t captureOutputMode;
} Timer_A_CaptureModeConfig;
captureRegister is the register/channel you want to use. Valid parameters include TIMER_A_CAPTURECOMPARE_REGISTER_0, TIMER_A_CAPTURECOMPARE_REGISTER_1, etc., up to TIMER_A_CAPTURECOMPARE_REGISTER_6.
captureMode sets when the capture is triggered. Your options are: TIMER_A_CAPTUREMODE_NO_CAPTURE (which is the default... but that's rather pointless, isn't it?), TIMER_A_CAPTUREMODE_RISING_EDGE, TIMER_A_CAPTUREMODE_FALLING_EDGE, and TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE.
captureInputSelect decides which input to capture from. The parameters are: TIMER_A_CAPTURE_INPUTSELECT_CCIxA (the default), TIMER_A_CAPTURE_INPUTSELECT_CCIxB, TIMER_A_CAPTURE_INPUTSELECT_GND, and TIMER_A_CAPTURE_INPUTSELECT_Vcc. What's the difference between CCIxA and CCIxB? According the to reference manual and the datasheet, CCIxA is used for external GPIO connections while CCIxB is used for internal hardware connections. As such, we will typically use CCIxA.
synchronizeCaptureSource determines whether the input is captured in sync with the Timer_A's clock. You may choose TIMER_A_CAPTURE_ASYNCHRONOUS or TIMER_A_CAPTURE_SYNCHRONOUS.
As the name suggests, captureInterruptEnable sets whether or not to trigger interrupts. Select either TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE or TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE.
The captureOutputMode can be useful if you want to drive an output using the Timer_A's input capture. If you don't want to do that, stick with the default TIMER_A_OUTPUTMODE_OUTBITVALUE. Otherwise, you have the same output mode options as you did with the PWM.
Once you have your struct set up, use the following function to configure the Timer_A for input capture:
extern void Timer_A_initCapture(uint32_t timer,
const Timer_A_CaptureModeConfig *config);
The timer parameter is the timer base you'd like to use, just like with PWM. The config parameter is a pointer to the config struct you've initialized, as explained above.
When the input capture is triggered, the counter value of the Timer_A clock is stored inside the capture-compare register. To access the register, use the following function:
extern uint_fast16_t Timer_A_getCaptureCompareCount(uint32_t timer,
uint_fast16_t captureCompareRegister);
The parameters for that function are identical to the ones mentioned in the previous sections above.
If you'd like to use interrupts with the input capture, note that it has its own function:
extern void Timer_A_enableCaptureCompareInterrupt(uint32_t timer,
uint_fast16_t captureCompareRegister);
The parameters for that function are identical to the ones mentioned in the sections above.
Note that you will likely want to enable the regular interrupt for Timer_A, too, to record any Timer_A rollovers:
extern void Timer_A_enableInterrupt(uint32_t timer);
To check if the input capture interrupt was triggered, use the following function:
extern uint32_t Timer_A_getCaptureCompareInterruptStatus(uint32_t timer,
uint_fast16_t captureCompareRegister, uint_fast16_t mask);
The first two parameters are self-explanatory. The mask parameter (and in fact, this entire function) behaves similarly to the identical parameter for UART's "get interrupt status" function. Valid values are: TIMER_A_CAPTURE_OVERFLOW and TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG. The function will return the result of your mask parameter OR'd with the interrupt register, just like a bitmask (which is exactly what the mask parameter is).