5 Replies Latest reply on Aug 3, 2018 6:35 AM by radic_2046471

    CapSenseCSD and ADC SAR simultaneously in PSoC-4

    radic_2046471

      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. Re: CapSenseCSD and ADC SAR simultaneously in PSoC-4
          wicoc_1641241

          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.

          • 2. Re: CapSenseCSD and ADC SAR simultaneously in PSoC-4
            rajivv_36

            Can you please check if the global interrupt is enabled?

             

            -Rajiv

            • 3. Re: CapSenseCSD and ADC SAR simultaneously in PSoC-4
              radic_2046471

              rajivv_36, the global interrupt is enabled.

              • 4. Re: CapSenseCSD and ADC SAR simultaneously in PSoC-4
                radic_2046471

                wicoc_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.

                • 5. Re: CapSenseCSD and ADC SAR simultaneously in PSoC-4
                  radic_2046471

                  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;   

                       }       

                  }

                   

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