This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Access ADC data

Other Parts Discussed in Thread: HALCOGEN

hi,

the TRM of TRM570 speaks about a ADEVBUFFER to access ADC data but this define is not defined (as many other) due to HalCoGen version change, I suppose.

AFAIK there are 3 ways to access ADC data:

  • direct access to the ADC RAM (fast but don't reset the interrupt threshold counter
  • FIFO access
  • adcGetData function generated by HalCoGen

Do the adcGetData is comparably slower than the other two methods?

Which is exactly the instruction to read a value from FIFO having the side effct of incrementing the threshold counter ? (please post a C example)

Inside the interrupt function, to implement a fast continuous double buffering is better:

  • increment the threshold counter by halfFifo size and then access ADC RAM directly (alternating the fist and the second half of the RAM
  • use the FIFO access that should (I've not tested it yet) auto increment the threshold count

Which one is better?

Which code does implement the second solution (please post an example compatible with CCSv5 and HalCoGen 03.06.00)

Thank you

  • Hello Matteo,

    The ADEVBUFFER is the data buffer for the EVENT Group. Likewise there is a set of buffers for G1 and G2. These buffers are defined by Halcogen in reg_adc.h file in Halcogen v3.06.00 and are used by the adcGetData function. These buffers will decrement the threshold counter when the FIFO buffer is accessed.

    In the function adcGetData generated by Halcogen, it will either read the total number of results indicated by the count threshold or by the entire group RAM size. Howeever, there would be efficiency drawbacks to using this function since the level of abstraction will add processing overhead.

    Accessing the ADC in CPU mode (i.e., direct access by the CPU to the ADC RAM) will not decrement the threshold counter so the software would have to manage this function if this method is used to read the ADC results for a given Group. The extra work to manage this would make your idea of double buffering less efficient with direct RAM access.

    In short, the fastest way would be to use similar algorithms as are used in the getADCData function within an ADC ISR but eliminate some of the overhead in the getADCData function since you know specifics about your implementation and don't have to build in overhead for checking for 12-bit vs. 10-bit, channel numbers, etc.

    Unfortunately, I don't really have any code setup for this type of impementation so I have no examples to offer.

     

  • Hello Chuck,

    sorry but there's no ADEVBUFFER in my reg_adc.h. There's a GxBuf[3] struct with BUF0, BUF1..BUF7 (commented as "Group 0-2 result buffer 1 register" but undocumented elsewhere) and there are EVEMUBUFFER, G1EMUBUFFER, G2EMUBUFFER inside the adcBASE_t struct.

    Which one of that is the ADEVBUFFER? What are the others?

    Supposing that EVEMUBUFFER is the right one, to access it in FIFO mode I shoud simply assign it's value to a var in system RAM to implement the "FIFO mode" mechanism (then to cause the threshold decrement)? Simply calling repeatedly an instruction like: myVar = adcREG1->EVEMUBUFFER will do the job?

    Thank you,

    Matteo

  • In attachment my HalCoGen v03.06.00 generated reg_adc.h

    reg_adc.zip
  • Matteo,

    The GxBuffer[3] array contains the FIFO locations for each of the three conversion groups. That is, GxBuffer[0] points to the FIFO location for the event group, GxBuffer[1] points to the FIFO location for Group1 and GxBuffer[2] points to the FIFO location for Group2. These essentially correspond to ADEVBUFFER, ADG1BUFFER and ADG2BUFFER in the reference manual.

    A read from any of these locations will read out one conversion result from the corresponding group's FIFO.

    Regards, Sunil

  • Hello Matteo,

    My apologies as I meant to point out that the GxBuf arrays are the ADEVBUFFER, ADG1BUFFER and ADG2BUFFER. If you look at the hex values in the comments you will see that these are the same offsets as the ADxxBUFFER registers documented in the TRM. These are the registers used for FIFO access.

    The xxEMUBUFFER registers serve a different purpose than the ADxxBUFFER registers. The EMU registers will also access the FIFO as you mentioned. However, this read will not affect any of the status flags in the group interupt flag registers or the group status flag register. These registers are useful for debuggers.

    For implementation, see the code for adcGetData() function generated by Halcogen. You can implement something similar in your ADC interrupt service routine to move the ADC data to RAM. In short, each time you read the value of GxBUF, it will access the FIFO buffer and the FIFO pointer will be adjusted to the next data in the buffer. So, if you are moving results to RAM, you would simply always read GxBuf[x] (where x = the group number considering EV=0, G1=1, and G2=2) and move the value to the RAM location where the result is to be stored.

    In regard to the threshold counter, I want to clarify the increment/decrement process. Once you set the threshold counter, each converted value will be written to ADC RAM sequentially and the threshold count will be decremented for each conversion written. When you read out the results, the counter is incremented. Note that if more conversions are written to the ADC RAM Buffers than the threshold count, it is possible for the counter to roll below zero. When this occurs, you can subtract the counter from the original threshold value to see how many ADC results there are to read allowing some dynamic ability in regard to the size of the double buffering.

  • Hi Chuck,

    thank you for the answer. To be complete: (GxBUF is defined as a struct, what are the BUF0...BUF7 registers inside the GxBUF[n]?

    According to the "adcGetData" function implemetation to read the FIFO  I simply do something like:

    unit16 val = (uint16)( adc->GxBUF[group].BUF0 & 0xFFFU);

    so what BUF1 to BUF7 are meant for?

    Thank you

  • Hello Matteo,

    The BUF0-BUF7 are provided for the specfic intent of using the LDM instruction with the ADC results from the FIFO. This allows greater efficiency when reading the results.

    It also allows out of sequence reading of the results. For example, if you need the first result in the list you would read BUF0; the second, BUF1; third, BUF2; etc. Whenever a result is read, it is removed fromt he FIFO and following results move up one spot in the list. If you read BUF0 continuously, you would simply read out the results serially and if you read BUF one continuously, you would read teh results serially but skip the first result in the FIFO (BUF0).