CapSenseCSD and ADC SAR simultaneously in PSoC-4

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi!
I'm developing a battery powered project with the CY8C4126AXI-M443 that uses the CapSense and is working very fine.

Now I have to measure the battery voltage and to do that, I'm using the ADC_SAR_Seq component.

I configured the adc module and added into the project. The problem that I'm dealing is that the processing of main function freezes on the calling of the first capsense function.

Bellow I provides a piece of code with the implementation of Capsense and ADC setup.

The processing freeze on CapSense_ScanSensor function.

- main.c --------------------------------------------------------------------------------

void main( void )
{
    /* Start CapSense component */
    CapSense_Start();
    CapSense_SetDebounce( CapSense_SENSOR_PROX_0__PROX, 2 );

    /* Set resolution of proximity sensor to 16 bit for maximum possible
     * proximity sensing distance
     */
    CapSense_SetScanResolution( CapSense_PROX__PROX, CapSense_RESOLUTION_16_BITS);

    /* Scan sensors and initialize baselines */
    CapSense_InitializeSensorBaseline(CapSense_SENSOR_PROX_0__PROX);

    /* Initialize Advanced Low Pass (ALP) filter with current raw count
     * value, and set the k value for ALP filter.
     * Note: Refer AN92239 for details on how to select appropriate k value
     * for the filter.
     */
    CapSenseFilters_InitializeAdvancedLowPass( CapSense_SENSOR_PROX_0__PROX, CapSense_ReadSensorRaw(CapSense_SENSOR_PROX_0__PROX) );
    CapSenseFilters_SetAdvancedLowPassK(CAPSENSEFILTERS_IIR_K_32);   
    CySysPmUnfreezeIo();

    (void)BatMonInit();
    BatMonStart();

    for(;;)
    {
        WdtReset();

        CapSense_ScanSensor(CapSense_SENSOR_PROX_0__PROX);

        while(CapSense_IsBusy())
        {          
            /* Wait until scan is complete */   
        }   

        /* Apply ALP filter on proximity sensors */
        CapSenseFilters_RunAdvancedLowPass(CapSense_SENSOR_PROX_0__PROX);
}

}

- batmon.c ------------------------------------------------------------------------------

void BatMonInit( void )
{
ADC_SAR_Seq_Init();
ADC_SAR_Seq_IRQ_StartEx( ADC_SAR_Seq_ISR );
}

void BatMonStart( void )
{
ADC_SAR_Seq_Start();
ADC_SAR_Seq_StartConvert();
return;
}

void ADC_SAR_Seq_ISR( void )
{
    uint32 intr_status;
    uint32 range_status;

    /* Read interrupt status registers */
    intr_status = ADC_SAR_Seq_SAR_INTR_MASKED_REG;
   
    /* Check for End of Scan interrupt */
    if((intr_status & ADC_SAR_Seq_EOS_MASK) != 0u)
    {
        /* Read range detect status */
        range_status = ADC_SAR_Seq_SAR_RANGE_INTR_MASKED_REG;
        /* Verify that the conversion result met the condition Low_Limit <= Result < High_Limit  */
        //if((range_status & (uint32)(1ul << CH0_N)) != 0u)
        {
            /* Read conversion result */
            result[CH0_N] = ADC_SAR_Seq_GetResult16(CH0_N);
        }   

        /* Clear range detect status */
        ADC_SAR_Seq_SAR_RANGE_INTR_REG = range_status;
        dataReady |= ADC_SAR_Seq_EOS_MASK;
    }       
}

-----------------------------------------------------------------------------------------

1 Solution
wcc3
Level 4
Level 4
10 likes received 10 replies posted 5 replies posted

One thing that sticks out a bit is that you don't seem to be clearing the ADC's end-of-sequence interrupt flag.

My ADC interrupt handlers start with these four lines:

    /* Read interrupt status registers and clear interrupt flags. */

    uint32 intr_status = ADC_SAR_Seq_SAR_INTR_MASKED_REG;

    uint32 range_status = ADC_SAR_Seq_SAR_RANGE_INTR_MASKED_REG;

    ADC_SAR_Seq_SAR_INTR_REG = intr_status;

    ADC_SAR_Seq_SAR_RANGE_INTR_REG = range_status;

Then I go on about my business checking the bits in intr_status and range_status as you do.

View solution in original post

5 Replies
wcc3
Level 4
Level 4
10 likes received 10 replies posted 5 replies posted

One thing that sticks out a bit is that you don't seem to be clearing the ADC's end-of-sequence interrupt flag.

My ADC interrupt handlers start with these four lines:

    /* Read interrupt status registers and clear interrupt flags. */

    uint32 intr_status = ADC_SAR_Seq_SAR_INTR_MASKED_REG;

    uint32 range_status = ADC_SAR_Seq_SAR_RANGE_INTR_MASKED_REG;

    ADC_SAR_Seq_SAR_INTR_REG = intr_status;

    ADC_SAR_Seq_SAR_RANGE_INTR_REG = range_status;

Then I go on about my business checking the bits in intr_status and range_status as you do.

Anonymous
Not applicable

wcolley_1641241​, thank you. Your response helped me a lot. I used the example project that comes with the PSoC Creator as basis to my implementation. I discovered after your post and a quick reading on the ADC_SAR datasheet that the example have some mistakes.

I fixed the implementation observing the registers and the adc is working now.

The problem was that the ADC interrupt flags aren't been cleaned.

0 Likes
Anonymous
Not applicable

The ISR is thus implemented:

-----------------------------------------------------------------------------------------------------

void ADC_SAR_Seq_ISR( void )

{  

      uint32 intr_status;    

     /* Read interrupt status registers */   

     intr_status = ADC_SAR_Seq_SAR_INTR_REG;       

    

     /* Check for End of Scan interrupt */   

     if((intr_status & ADC_SAR_Seq_EOS_MASK) != 0u)   

     {       

          /* Read conversion result */       

          result[CH0_N] = ADC_SAR_Seq_GetResult16(CH0_N);        

    

          /* clear the interruption flag */       

          ADC_SAR_Seq_SAR_INTR_REG = intr_status;       

          dataReady |= ADC_SAR_Seq_EOS_MASK;   

     }       

}

-----------------------------------------------------------------------------------------------------

0 Likes
Anonymous
Not applicable

Can you please check if the global interrupt is enabled?

-Rajiv

Anonymous
Not applicable

rajiv.vasanth.badiger​, the global interrupt is enabled.

0 Likes