Hi Everyone,
Im new to using Kinetis microcontrollers and I have a TWR-K65F180M board that I'm trying to use to capture inputs from an encoder. I am working off of the PWM_twochannel driver example using SDK2.0. I have the FTM set up to use FTM2_CH0. The api document says that every time a rising edge is captured the counter value should be stored in the CnV register. However, unable to read any values in the CnV registers using the EmbSysRegView.
Thanks for any help!
Solved! Go to Solution.
Hello Jake,
Just as reference, here is the full example:
/*******************************************************************************
* Definitions
******************************************************************************/
#define BOARD_FTM_BASEADDR FTM2
#define BOARD_FIRST_FTM_CHANNEL 0U
#define BOARD_SECOND_FTM_CHANNEL 1U
/* Get source clock for FTM driver */
#define FTM_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
#define FTM_READ_INPUT_CAPTURE BOARD_FTM_BASEADDR->CONTROLS[BOARD_FIRST_FTM_CHANNEL].CnV
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Main function
*/
int main(void)
{
ftm_config_t ftmInfo;
uint32_t status = 0;
/* Board pin, clock, debug console init */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
/* Print a note to terminal */
PRINTF("\r\nFTM input capture example\r\n");
FTM_GetDefaultConfig(&ftmInfo);
/* Initialize FTM module */
FTM_Init(BOARD_FTM_BASEADDR, &ftmInfo);
PRINTF("FTM value: \r\n");
FTM_SetupInputCapture(BOARD_FTM_BASEADDR, BOARD_FIRST_FTM_CHANNEL, kFTM_RisingEdge, 0);
BOARD_FTM_BASEADDR->MOD = 0xFFFF;
FTM_StartTimer(BOARD_FTM_BASEADDR, kFTM_SystemClock);
while (1)
{
if (FTM_READ_INPUT_CAPTURE >= 20000) {
PRINTF("%d\r\n",FTM_READ_INPUT_CAPTURE);
}
status = FTM_GetStatusFlags(BOARD_FTM_BASEADDR);
if (status & kFTM_TimeOverflowFlag) {
FTM_ClearStatusFlags(BOARD_FTM_BASEADDR, status);
}
}
}
Hope this helps!
Regards,
Isaac
Hello Jake,
Sorry for late response. For input capture mode, you will need to set 0xFFFF to MOD register in order to use counter in free-running mode. Program should look like as follows:
#define FTM_READ_INPUT_CAPTURE BOARD_FTM_BASEADDR->CONTROLS[BOARD_FIRST_FTM_CHANNEL].CnV
ftm_config_t ftmInfo;
uint32_t status = 0;
/* Board pin, clock, debug console init */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
/* Print a note to terminal */
PRINTF("\r\nFTM input capture example\r\n");
FTM_GetDefaultConfig(&ftmInfo);
/* Initialize FTM module */
FTM_Init(BOARD_FTM_BASEADDR, &ftmInfo);
PRINTF("FTM value: \r\n");
FTM_SetupInputCapture(BOARD_FTM_BASEADDR, BOARD_FIRST_FTM_CHANNEL, kFTM_RisingEdge, 0);
BOARD_FTM_BASEADDR->MOD = 0xFFFF;
FTM_StartTimer(BOARD_FTM_BASEADDR, kFTM_SystemClock);
while (1)
{
if (FTM_READ_INPUT_CAPTURE >= 20000) {
PRINTF("%d\r\n",FTM_READ_INPUT_CAPTURE);
}
status = FTM_GetStatusFlags(BOARD_FTM_BASEADDR);
if (status & kFTM_TimeOverflowFlag) {
FTM_ClearStatusFlags(BOARD_FTM_BASEADDR, status);
}
}
If you try this code, you will be able to print on screen counter value.
I hope this can help you!
Regards,
Isaac
Isaac,
Thanks for the help. I am still having some issues with the BOARD_FIRST_FTM_CHANNEL. Just to clarify I need to define BOARD_FIRST_FTM_CHANNEL as kFTM_Chnl_0 and BOARD_FTM_BASEADDR as FTM2 to capture input from FTM2_CH0 that will measure the time between riding edges and print this to the screen.
Thanks again
Hello Jake,
Just as reference, here is the full example:
/*******************************************************************************
* Definitions
******************************************************************************/
#define BOARD_FTM_BASEADDR FTM2
#define BOARD_FIRST_FTM_CHANNEL 0U
#define BOARD_SECOND_FTM_CHANNEL 1U
/* Get source clock for FTM driver */
#define FTM_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
#define FTM_READ_INPUT_CAPTURE BOARD_FTM_BASEADDR->CONTROLS[BOARD_FIRST_FTM_CHANNEL].CnV
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Main function
*/
int main(void)
{
ftm_config_t ftmInfo;
uint32_t status = 0;
/* Board pin, clock, debug console init */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
/* Print a note to terminal */
PRINTF("\r\nFTM input capture example\r\n");
FTM_GetDefaultConfig(&ftmInfo);
/* Initialize FTM module */
FTM_Init(BOARD_FTM_BASEADDR, &ftmInfo);
PRINTF("FTM value: \r\n");
FTM_SetupInputCapture(BOARD_FTM_BASEADDR, BOARD_FIRST_FTM_CHANNEL, kFTM_RisingEdge, 0);
BOARD_FTM_BASEADDR->MOD = 0xFFFF;
FTM_StartTimer(BOARD_FTM_BASEADDR, kFTM_SystemClock);
while (1)
{
if (FTM_READ_INPUT_CAPTURE >= 20000) {
PRINTF("%d\r\n",FTM_READ_INPUT_CAPTURE);
}
status = FTM_GetStatusFlags(BOARD_FTM_BASEADDR);
if (status & kFTM_TimeOverflowFlag) {
FTM_ClearStatusFlags(BOARD_FTM_BASEADDR, status);
}
}
}
Hope this helps!
Regards,
Isaac