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

cross mob
BhSr_4843381
Level 3
Level 3
25 sign-ins 10 replies posted 10 questions asked

Hello, 

I have been working on the PSoC 5LP SAR ADCs. In my current project, I am driving an Analog mux with a single input from an IDAC and the outputs of the MUX is given alternatively to the SAR ADC. If I am sampling at 50K SPS, I have been told to acquire all the output data from the SAR that can be sampled within 0.1s/100ms and store all of these values in a buffer. I wanted to know a couple of things. 

1. I am running in software trigger-mode. As per my understanding, the EOC pin output from the ADC is an output pin from the ADC that gives a rising edge when one conversion per channel is sampled. However, when I connect a GPIO input pin to the EOC pin it gives an error "Too many drivers present on this pin", but it does not give me an error when I connect a digital output pin. Is my understanding wrong?

2. Since there is a status register (ADC_SAR_SEQ_STATUS_REG ) with the EOC bit, I want to use this status bit as a counter to acquire data, ie, I want to get result from ADC, everytime this bit is set. Will this be a good way to store all samples? Also in the datasheet there is a mention of a global variable - ADC_SAR_Seq_finalArray. Instead of using EOC and get result, does this array already have all the 50K samples every second stored in it and can I use it directly?

 

Thanks in advance.

0 Likes
1 Solution

BhSr,

In general what you say is correct. 

Your code fragment is intended for the polling implementation.  However I would suggest a change to it:

ADC_2_StartConvert();
// CyDelayUs(15);  Not needed if you use ADC_2_IsEndConversion()
for(i=0; i<5000; i++)
{
   while (ADC_w_IsEndConversion() == 0) {}  // Wait until the conversion is completed
   array[i] = ADC_2_GetResult16(0);
}
ADC_2_StopConvert();

If you use an ISR for the EOC output then you can eliminate the ADC_2_IsEndConversion()

uint16_t array[5000];
uint16_t array_idx = 0;

CY_ISR(isr_eoc)
{
  array[array_idx] = ADC_2_GetResult16(0);
  array_idx++;
}
Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
4 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

BhSr,

 

... However, when I connect a GPIO input pin to the EOC pin it gives an error "Too many drivers present on this pin", but it does not give me an error when I connect a digital output pin. Is my understanding wrong?


The GPIO input pin attached to the EOC output is definitely the problem.   The GPIO input pin has an output as an internal connection.  The EOC is an output. Attached to the output of the GPIO input.   Attaching the EOC output to the GPIO output pin will allow you to read the EOC signal.


2. Since there is a status register (ADC_SAR_SEQ_STATUS_REG ) with the EOC bit, I want to use this status bit as a counter to acquire data, ie, I want to get result from ADC, everytime this bit is set. Will this be a good way to store all samples? Also in the datasheet there is a mention of a global variable - ADC_SAR_Seq_finalArray. Instead of using EOC and get result, does this array already have all the 50K samples every second stored in it and can I use it directly?


ADC_SAR_Seq_finalArray is used to store ONE sample of each channel of the input Mux not multiple samples of one channel.

There are many options for you to chose:

  • Read the EOC bit in the ADC_SAR_SEQ_STATUS_REG as you mentioned using SW polling.  It will be very SW intensive.  It is the 'easiest' implementation.
  • Attach an ISR to the EOC output.   The ISR can be coded to store the 50K samples in a buffer.  SW-intensive polling is not needed.  More efficient.   You need to handle the 50K buffer and when all samples are acquired.
     
    Len_CONSULTRON_9-1611749824956.png
     
     
     
     
     
     
  • Attach a DMA component to the EOC output.  The DMA can be configured to automatically load the samples into a 50K buffer.  Each sample acquired automatically increments the pointer to the next sample address.   This is the MOST efficient use of the CPU and occurs with extremely little latency.  Although elegant and efficient, it does require a more careful effort in coding. 
    An ISR can be attached to the DMA component to launch an interrupt when all the required samples are completed.  In the interrupt, you can start processing the data as needed.
    Len_CONSULTRON_11-1611750174365.png

     

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Hello, 

Thank you for your detailed response. I will attempt to use the interrupt method as that seems the easiest to go forward. 

However, I had a different idea in mind which I wanted to try, do let me know if this is an efficient method to achieve the same result. If I am sampling my ADC at 50000 SPS (Channel Sample Rate- 100KSPS) and I want to complete my acquisition in 0.1s and I just need 5000 of the samples stored, not the entire 50000 that is acquired in 1s: 

As far as my understanding goes, the ADC_SAR_Seq_finalArray stores one sample of each channel when a conversion happens AND every time the EOC bit is set. And the ADC_GetResult16() function returns this array after taking care of the offset. So if I were to write a for loop in the following way:

ADC_2_StartConvert();
CyDelayUs(15);
for(i=0; i<5000; i++){
array[i] = ADC_2_GetResult16(0);
}
ADC_2_StopConvert();

 

Will this achieve my desired result, ie, get 5000 samples within 100ms? Will ADC_GetResult16() function update every time the counter (i) is incremented and give me the result of every sample?

0 Likes

BhSr,

In general what you say is correct. 

Your code fragment is intended for the polling implementation.  However I would suggest a change to it:

ADC_2_StartConvert();
// CyDelayUs(15);  Not needed if you use ADC_2_IsEndConversion()
for(i=0; i<5000; i++)
{
   while (ADC_w_IsEndConversion() == 0) {}  // Wait until the conversion is completed
   array[i] = ADC_2_GetResult16(0);
}
ADC_2_StopConvert();

If you use an ISR for the EOC output then you can eliminate the ADC_2_IsEndConversion()

uint16_t array[5000];
uint16_t array_idx = 0;

CY_ISR(isr_eoc)
{
  array[array_idx] = ADC_2_GetResult16(0);
  array_idx++;
}
Len
"Engineering is an Art. The Art of Compromise."
0 Likes

This is great, thank you very much for the response. I'll configure the ISR as you have suggested. 

0 Likes