MCUXpresso_LPC845/devices/LPC845/drivers/fsl_capt.c

305 lines
9.4 KiB
C

/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_capt.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.capt"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get the CAPT instance from the peripheral base address.
*
* @param base CAPT peripheral base address.
* @return CAPT instance.
*/
static uint32_t CAPT_GetInstance(CAPT_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of CAPT peripheral base address. */
static CAPT_Type *const s_captBases[] = CAPT_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Clock name of CAPT. */
static const clock_ip_name_t s_captClock[] = CAPT_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_CAPT_HAS_NO_RESET) && FSL_FEATURE_CAPT_HAS_NO_RESET)
/*! @brief Pointers to CAPT resets for each instance. */
static const reset_ip_name_t s_captResets[] = CAPT_RSTS_N;
#endif
/*******************************************************************************
* Codes
******************************************************************************/
static uint32_t CAPT_GetInstance(CAPT_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_captBases); instance++)
{
if (s_captBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_captBases));
return instance;
}
/*!
* brief Initialize the CAPT module.
*
* param base CAPT peripheral base address.
* param config Pointer to "capt_config_t" structure.
*/
void CAPT_Init(CAPT_Type *base, const capt_config_t *config)
{
assert(config != NULL);
uint32_t tmp32;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Open clock gate. */
CLOCK_EnableClock(s_captClock[CAPT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#if !(defined(FSL_FEATURE_CAPT_HAS_NO_RESET) && FSL_FEATURE_CAPT_HAS_NO_RESET)
/* Reset the CAPT module */
RESET_PeripheralReset(s_captResets[CAPT_GetInstance(base)]);
#endif
/* Write CTRL register. */
tmp32 = base->CTRL & (CAPT_CTRL_POLLMODE_MASK | CAPT_CTRL_TYPE_MASK
#if defined(FSL_FEATURE_CAPT_HAS_CTRL_DMA) && FSL_FEATURE_CAPT_HAS_CTRL_DMA
| CAPT_CTRL_DMA_MASK
#endif /* FSL_FEATURE_CAPT_HAS_CTRL_DMA */
);
tmp32 |= CAPT_CTRL_TRIGGER(config->triggerMode) | CAPT_CTRL_FDIV(config->clockDivider) |
CAPT_CTRL_XPINUSE(config->XpinsMode) | CAPT_CTRL_XPINSEL(config->enableXpins);
if (config->enableWaitMode)
{
tmp32 |= CAPT_CTRL_WAIT_MASK;
}
/* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
{
}
base->CTRL = tmp32;
/* Write POLL_TCNT register. */
tmp32 = base->POLL_TCNT & CAPT_POLL_TCNT_TCNT_MASK;
tmp32 |= CAPT_POLL_TCNT_TOUT(config->timeOutCount) | CAPT_POLL_TCNT_POLL(config->pollCount) |
CAPT_POLL_TCNT_MDELAY(config->mDelay) | CAPT_POLL_TCNT_RDELAY(config->rDelay);
if (config->enableTouchLower)
{
tmp32 |= CAPT_POLL_TCNT_TCHLOW_ER_MASK;
}
base->POLL_TCNT = tmp32;
}
/*!
* brief De-initialize the CAPT module.
*
* param base CAPT peripheral base address.
*/
void CAPT_Deinit(CAPT_Type *base)
{
/* Make CAPT inactive. */
/* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
{
}
base->CTRL &= ~CAPT_CTRL_POLLMODE_MASK;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable clock gate. */
CLOCK_DisableClock(s_captClock[CAPT_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Gets an available pre-defined settings for the CAPT's configuration.
*
* This function initializes the converter configuration structure with available settings. The default values are:
* code
* config->enableWaitMode = false;
* config->enableTouchLower = true;
* config->clockDivider = 15U;
* config->timeOutCount = 12U;
* config->pollCount = 0U;
* config->enableXpins = 0U;
* config->triggerMode = kCAPT_YHPortTriggerMode;
* config->XpinsMode = kCAPT_InactiveXpinsDrivenLowMode;
* config->mDelay = kCAPT_MeasureDelayNoWait;
* config->rDelay = kCAPT_ResetDelayWait9FCLKs;
* endcode
* param base CAPT peripheral base address.
* param config Pointer to the configuration structure.
*/
void CAPT_GetDefaultConfig(capt_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));
config->enableWaitMode = false;
config->enableTouchLower = true;
config->clockDivider = 15U;
config->timeOutCount = 12U;
config->pollCount = 0U;
config->enableXpins = 0U;
config->triggerMode = kCAPT_YHPortTriggerMode;
config->XpinsMode = kCAPT_InactiveXpinsDrivenLowMode;
config->mDelay = kCAPT_MeasureDelayNoWait;
config->rDelay = kCAPT_ResetDelayWait9FCLKs;
}
/*!
* brief Set the CAPT polling mode.
*
* param base CAPT peripheral base address.
* param mode The selection of polling mode.
*/
void CAPT_SetPollMode(CAPT_Type *base, capt_polling_mode_t mode)
{
/* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
{
}
base->CTRL &= ~CAPT_CTRL_POLLMODE_MASK;
base->CTRL |= CAPT_CTRL_POLLMODE(mode);
}
#if defined(FSL_FEATURE_CAPT_HAS_CTRL_DMA) && FSL_FEATURE_CAPT_HAS_CTRL_DMA
/*!
* brief Enable DMA feature.
*
* param base CAPT peripheral base address.
* param mode Select how DMA triggers are generated.
*/
void CAPT_EnableDMA(CAPT_Type *base, capt_dma_mode_t mode)
{
/* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
{
}
base->CTRL = (base->CTRL & ~CAPT_CTRL_DMA_MASK) | CAPT_CTRL_DMA(mode);
}
/*!
* brief Disable DMA feature.
*
* param base CAPT peripheral base address.
*/
void CAPT_DisableDMA(CAPT_Type *base)
{
/* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
while (CAPT_CTRL_INCHANGE_MASK == (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
{
}
base->CTRL &= ~CAPT_CTRL_DMA_MASK;
}
#endif /*FSL_FEATURE_CAPT_HAS_CTRL_DMA*/
/*!
* brief Get CAPT touch data.
*
* param base CAPT peripheral base address.
* param data The structure to store touch data.
*
* return If return 'true', which means get valid data.
* if return 'false', which means get invalid data.
*/
bool CAPT_GetTouchData(CAPT_Type *base, capt_touch_data_t *data)
{
assert(NULL != data);
uint32_t tmp32;
bool ret;
tmp32 = base->TOUCH;
if (CAPT_TOUCH_CHANGE_MASK == (CAPT_TOUCH_CHANGE_MASK & tmp32))
{
ret = false;
}
else
{
if (CAPT_TOUCH_ISTOUCH_MASK == (CAPT_TOUCH_ISTOUCH_MASK & tmp32))
{
data->yesTouch = true;
}
else
{
data->yesTouch = false;
}
if (CAPT_TOUCH_ISTO_MASK == (CAPT_TOUCH_ISTO_MASK & tmp32))
{
data->yesTimeOut = true;
}
else
{
data->yesTimeOut = false;
}
data->XpinsIndex = (uint8_t)((CAPT_TOUCH_XVAL_MASK & tmp32) >> CAPT_TOUCH_XVAL_SHIFT);
data->sequenceNumber = (uint8_t)((CAPT_TOUCH_SEQ_MASK & tmp32) >> CAPT_TOUCH_SEQ_SHIFT);
data->count = (uint16_t)((CAPT_TOUCH_COUNT_MASK & tmp32) >> CAPT_TOUCH_COUNT_SHIFT);
ret = true;
}
return ret;
}
/*
* brief Start touch data polling using poll-now method.
*
* This function starts new data polling using polling-now method, CAPT stops when
* the polling is finished, application could check the status or monitor interrupt
* to know when the progress is finished.
*
* Note that this is simultaneous poll of all X pins, all enabled X pins are
* activated concurrently, rather than walked one-at-a-time
*
* param base CAPT peripheral base address.
* param enableXpins The X pins enabled in this polling.
*/
void CAPT_PollNow(CAPT_Type *base, uint16_t enableXpins)
{
/* Before writing into CTRL register, INCHANGE(bit 15)should equal '0'. */
while (0U != (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
{
}
/* If poll mode is not 0, change to 0. */
if (0U != (base->CTRL & CAPT_CTRL_POLLMODE_MASK))
{
base->CTRL &= ~CAPT_CTRL_POLLMODE_MASK;
while (0U != (CAPT_CTRL_INCHANGE_MASK & base->CTRL))
{
}
}
base->CTRL = (base->CTRL & ~(CAPT_CTRL_XPINSEL_MASK)) | CAPT_CTRL_POLLMODE(kCAPT_PollNowMode) |
CAPT_CTRL_XPINSEL(enableXpins);
}