CSD (CapSense Sigma Delta)¶

group group_csd

The CSD HW block enables multiple sensing capabilities on PSoC devices, including self-cap and mutual-cap capacitive touch sensing solutions, a 10-bit ADC, IDAC, and Comparator.

The CapSense solution includes:

• The CapSense Configurator tool, which is a configuration wizard to create and configure CapSense widgets. It can be launched in ModusToolbox from the CSD personality as well as in standalone mode. It contains separate documentation on how to create and configure widgets, parameters, and algorithm descriptions.

• An API to control the design from the application program. This documentation describes the API with code snippets about how to use them.

• The CapSense Tuner tool for real-time tuning, testing, and debugging, for easy and smooth design of human interfaces on customer products. The Tuner tool communicates with a device through a HW bridge and communication drivers (EzI2C, UART, etc.) and allows monitoring of widget statuses, sensor signals, detected touch positions, gestures, etc. The application program does not need to interact with the CSD driver and/or other drivers such as GPIO or SysClk directly. All of that is configured and managed by middleware.

This section describes only the CSD driver. Refer to the corresponding sections for documentation of middleware supported by the CSD HW block.

The CSD driver is a low-level peripheral driver that provides an interface to a complex mixed signal of the CSD HW block.

The CSD driver alone does not provide system-level functions. Instead, it is used by upper-level middleware to configure the CSD HW block required by an application.

The CSD HW block can support only one function at a time. To allow seamless time-multiplex implementation of functionality and to avoid conflicting access to hardware from the upper level, the CSD driver also implements a lock semaphore mechanism.

The CSD driver supports re-entrance. If a device contains several CSD HW blocks, the same CSD driver is used to configure any HW block. For that, each function of the CSD driver contains a base address to define the CSD HW block to which the CSD driver communicates.

For dual-core devices, the CSD driver functions can be called either by the CM0+ or CM4 cores. In case both cores need access to the CSD Driver, you should properly manage the memory access.

There is no restriction on the CSD Driver usage in RTOS.

Usage

The CSD driver is simple wrapper driver specifically designed to be used by higher level middleware. Hence, is highly not recommended to use CSD driver directly in the application program. To incorporate CSD HW block functionality in the application program, an associated middleware should be used.

The CSD Driver can be used to implement a custom sensing solution. In such a case, the application program must acquire and lock the CSD HW block prior to accessing it.

Setting up and using the CSD driver can be summed up in these four stages:

• Define configuration in the config structure.

• Allocate context structure variable for the driver.

• Capture the CSD HW block.

• Execute the action required to perform any kind of conversion.

The following code snippet demonstrates how to capture the CSD HW block for custom implementation:


/*
* Scenario: Need to perform a conversion. It is supposed that Pins, Clock,
* Interrupt, pre-charge and scanning configs are already prepared.
*/

/*...*/
cy_en_csd_key_t key;
cy_en_csd_status_t status;

/* Allocate CSD configuration structure and initialize it with user's configuration */
const cy_stc_csd_config_t customConfig = PRECHARGE_CONFIG;

/* Check if the CSD block if free */
key = Cy_CSD_GetLockStatus(CSD0, &csdContext);
if (CY_CSD_NONE_KEY == key)
{
/* Capture the CSD block and initialize it with user's configuration */
status = Cy_CSD_Init(CSD0, &customConfig, CY_CSD_USER_DEFINED_KEY, &csdContext);
/* Check if the CSD block was captured successfully */
if (CY_CSD_SUCCESS == status)
{
/* Block is captured successfully. User's application code can be placed and executed here. */
}
}
/*...*/


The entire solution, either CapSense or CSDADC, in addition to the CSD HW block, incorporates the following instances:

• Clocks

• Reference Voltage Input

• Interrupts

• GPIO Pins

The CSD driver does not configure those blocks and they should be managed by an upper level. When using CapSense or CSDADC, those blocks are managed by middleware.

Clocks

The CSD HW block requires a peripheral clock (clk_peri) input. It can be assigned using two methods:

• Using the Device Configurator (Peripheral-Clocks tab ).

• Using the SysClk (System Clock) driver. Refer to SysClk (System Clock) driver section for more details. If middleware is used, the clock is managed by middleware.

GPIO Pins

Any analog-capable GPIO pin that can be connected to an analog multiplexed bus (AMUXBUS) can be connected to the CSD HW block as an input.

GPIO input can be assigned to the CSD HW block using the following methods:

If middleware is used, pin configuration is managed by middleware. When using the CSD driver for custom implementation, the application program must manage pin connections.

Each AMUXBUS can be split into multiple segments. Ensure the CSD HW block and a GPIO belong to the same bus segment or join the segments to establish connection of the GPIO to the CSD HW block.

Reference Voltage Input

The CSD HW block requires a reference voltage input to generate programmable reference voltage within the CSD HW block. There are two on-chip reference sources:

• VREF

• AREF

For more information about specification and startup of reference voltage sources, refer to the SysAnalog (System Analog Reference Block) driver prior to making the selection.

Interrupts

The CSD HW block has one interrupt that can be assigned to either the Cortex M4 or Cortex M0+ core. The CSD HW block can generate interrupts on the following events:

• End of sample: when scanning of a single sensor is complete.

• End of initialization: when initialization of an analog circuit is complete.

• End of measurement: when conversion of an CSDADC channel is complete.

Additionally, the CSD interrupt can wake the device from the Sleep power mode. The CSD HW block is powered down in the Deep Sleep or Hibernate power modes. So, it cannot be used as a wake-up source in these power modes.

If a CapSense or ADC middleware is used, the interrupt service routine is managed by middleware. When using the CSD driver for custom implementation or other middleware, the application program must manage the interrupt service routine.

Implement an interrupt routine and assign it to the CSD interrupt. Use the pre-defined enumeration as the interrupt source of the CSD HW block. The CSD interrupt to the NVIC is raised any time the intersection (logic AND) of the interrupt flags and the corresponding interrupt masks are non-zero. The peripheral interrupt status register should be read in the ISR to detect which condition generated the interrupt. The appropriate interrupt registers should be cleared so that subsequent interrupts can be handled.

The following code snippet demonstrates how to implement a routine to handle the interrupt. The routine is called when a CSD interrupt is triggered.


void snippet_Cy_CSD_IntHandler(void)
{
uint32_t intrStatus;

/* Read interrupt status register */

/* Check an event that triggered the interrupt */
if ((intrStatus & CSD_INTR_SET_SAMPLE_Msk) == CSD_INTR_SET_SAMPLE_Msk)
{
/* End of scan occurred, get the result and do something with it here */
}

/* Clear pending interrupt */
Cy_CSD_WriteReg(CSD0, CY_CSD_REG_OFFSET_INTR, intrStatus);

}


The following code snippet demonstrates how to configure and enable the CSD interrupt:


const cy_stc_sysint_t CSD0_ISR_cfg =
{
#if (CY_CPU_CORTEX_M0P)
#if (CY_IP_M4CPUSS_VERSION == 1)
.intrSrc = NvicMux8_IRQn,       /* CM0+ interrupt is NVIC #8 */
#else
.intrSrc = NvicMux7_IRQn,       /* CM0+ interrupt is NVIC #7 */
#endif
.cm0pSrc = csd_interrupt_IRQn,  /* Source of NVIC #8 is the CSD interrupt */
.intrPriority = 3u,             /* Interrupt priority is 3 */
#else
.intrSrc = csd_interrupt_IRQn,  /* Interrupt source is the CSD interrupt */
.intrPriority = 3u,             /* Interrupt priority is 3 */
#endif
};

/* Configure the interrupt with vector at snippet_Cy_CSD_IntHandler() */
(void)Cy_SysInt_Init(&CSD0_ISR_cfg, snippet_Cy_CSD_IntHandler);

/* Enable the interrupt */
NVIC_EnableIRQ(CSD0_ISR_cfg.intrSrc);

/* Enable the CSD SAMPLE interrupt mask */



Alternatively, instead of handling the interrupts, the Cy_CSD_GetConversionStatus() function allows for firmware polling of the CSD block status.

Power Modes

The CSD HW block can operate in Active and Sleep CPU power modes. It is also possible to switch between Low power and Ultra Low power system modes. In Deep Sleep and in Hibernate power modes, the CSD HW block is powered off. When the device wakes up from Deep Sleep, the CSD HW block resumes operation without the need for re-initialization. In the case of wake up from Hibernate power mode, the CSD HW block does not retain configuration and it requires re-initialization.

note

1. The CSD driver does not provide a callback function to facilitate the low-power mode transitions. The responsibility belongs to an upper level that uses the CSD HW block to ensure the CSD HW block is not busy prior to a power mode transition.

2. A power mode transition is not recommended while the CSD HW block is busy. The CSD HW block status must be checked using the Cy_CSD_GetStatus() function prior to a power mode transition. Instead, use the same power mode for active operation of the CSD HW block. This restriction is not applicable to Sleep mode and the device can seamlessly enter and exit Sleep mode while the CSD HW block is busy.

warning

1. Do not enter Deep Sleep power mode if the CSD HW block conversion is in progress. Unexpected behavior may occur.

2. Analog start up time for the CSD HW block is 25 us. Initiate any kind of conversion only after 25 us from Deep Sleep / Hibernate exit.

Refer to the