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.

Analog Inputs + Starterware



Hello,

I observed some strange behavior while working with Starterware on BeagleBone regarding the Analog Inputs.

First of all, the SW-context:

Currently i´m programming some object oriented classes (Arduino Style) based on Starterware-Examples. In my Application i (can) use in parallel:

-Ethernet (TCP/IP) @ 100 Mbit (Thanks a lot to Tim49804 for his "interrupt workaround", in my stess-test i could transfer over 30 GB data @ 8 MB/s) with lwip 1.4.0
-UART0 @115200
-2x SPI @24 MHz
-All GPIOs (reconfigurable @runtime)
-(AN0 to AN7 , with limitations)

Additional:

-Starterware Version 02.00.00.07; Code Composer Studio 5.2.1.00018;
-D and I-Cache Enabled; Clock @ 720 MHz;

My Problems with "tsc_adc" @ Starterware API:

1. StepConfigure

I observed Measurements from wrong Channels. For Singleshot-Measurements of Analog 0 to Analog 6 I predefined the steps:

    //Define Measurements for all accesible analog Inputs, select needed "step" later. Single Measurements to Fifo0
    StepConfigure(1, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL1+1); // Configure step 1 for channel 1(AIN0)
    StepConfigure(2, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL2+1); //(AIN1)
    StepConfigure(3, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL3+1); //(AIN2)
    ...
    StepConfigure(7, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL7+1); //(AIN6)

Step Configure expands to:

void BBgpio::StepConfigure(unsigned int stepSel, unsigned int fifo,
                   unsigned int positiveInpChannel)
{
    /* Configure ADC to Single ended operation mode */
    TSCADCTSStepOperationModeControl(SOC_ADC_TSC_0_REGS, TSCADC_SINGLE_ENDED_OPER_MODE, stepSel);
    TSCADCTSStepConfig(SOC_ADC_TSC_0_REGS, stepSel, TSCADC_NEGATIVE_REF_VSSA,
                    positiveInpChannel, TSCADC_NEGATIVE_INP_ADCREFM, TSCADC_POSITIVE_REF_VDDA);
    TSCADCTSStepFIFOSelConfig(SOC_ADC_TSC_0_REGS, stepSel, fifo); /* select fifo 0 or 1*/
    TSCADCTSStepModeConfig(SOC_ADC_TSC_0_REGS, stepSel, TSCADC_ONE_SHOT_SOFTWARE_ENABLED); /* Configure ADC to one shot mode */
}

Without the workaround "+1" the constant TSCADC_POSITIVE_INP_CHANNEL1 is defined (0), TSCADC_POSITIVE_INP_CHANNEL2 is defined (1) and so on.
Activation of step 1 and 2 (without "+1") both resulted in Measurements of AIN0, Step 3 up to Step 6 resulted in Measurements of AIN1 to AIN5. At AIN6, no measurement was possible.
After incrementing all constants (defined at "tsc_adc.h") with +1, the channel and values of AIN0 to AIN6 are correct.

Qestions:
Am I missing something?
Are the Analog Inputs not mapped correctly at Beaglebone? (schematic seems ok)
Any suggestions?


Reading the ID with  (without "+1") TSCADCFIFOChannelIDRead (...) resulted in 0 to 6, what seems correct !?
Which leads to the second problem:

2. Fifo-read:

After sampling in Oneshot-mode, reading the resuts witch TSCADCFIFOADCDataRead (...) works fine.
But reading the ADC-Channel ID with TSCADCFIFOChannelIDRead(...) (if option is activated)  for the next single sample and then getting the sample with TSCADCFIFOADCDataRead (...)  results in 0.

Question:Is it possible that reading the Channel ID shifts the FIFO and the corresponding data is lost?

If yes, i will directly access FIFO0DATA Register and split ADCCHNLID and ADCDATA manually with a singel read.

3. Interrupt-Skipping

I trigger single Measurements for my higher API. Therefor i call following (trimmed) method:

int BBgpio::analogReadExt(unsigned int BBgpio){
...
    //Clear fifo
    do{
        words = TSCADCFIFOWordCountRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0); //Data in Fifo?
        TSCADCFIFOADCDataRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);            //Dummy read
    }while(words>0);

//Deadlock could be possible, if Interrupts are not active. Activate them for sure for ADC.
IntRegister(SYS_INT_ADC_TSC_GENINT, ADCIsr);
IntPrioritySet(SYS_INT_ADC_TSC_GENINT, 0x15, AINTC_HOSTINT_ROUTE_IRQ);
IntSystemEnable(SYS_INT_ADC_TSC_GENINT);
... ... ...

//Enable and config corresponding to Analog Pin, activate steps
switch(BBgpio){
case A0:
    TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 1, 1);
    break;
... ... ... ...
case A6:
    TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 7, 1);
    break;
default        : return ADC_NO_PIN;//no such pin accessible
}
...

adc_read=false;
adc_isr=false;
TSCADCIntStatusClear(SOC_ADC_TSC_0_REGS, 0x7FF); // Clear the status of all ADC interrupts

TSCADCEventInterruptEnable(SOC_ADC_TSC_0_REGS, TSCADC_END_OF_SEQUENCE_INT); // End of sequence interrupt is enable */

TSCADCModuleStateSet(SOC_ADC_TSC_0_REGS, TSCADC_MODULE_ENABLE); // Enable the TSC_ADC_SS module

//Deadlock Candidate
while(adc_isr==false){
    adc_isr_timeout_count++;
    if(adc_isr_timeout_count>=ADC_TIMEOUT_VALUE){
        return ADC_TIMEOUT;
    }
}

//Some error-Handling

....

    return analog_measurement;
}

Problem: Activating TSC_ADC_SS module sometimes doesn´t result in an interrupt (probability 0.048%). Therefore waiting for the Flag could result in a Deadlock.

The code in Yellow generates a Timeout without interrupts or using Watchdogs(because I can not guarantee the availability of these resources) after approximately 7us.

The ADC-ISR:

static void ADCIsr()
{
    volatile unsigned int status;

    status = TSCADCIntStatus(SOC_ADC_TSC_0_REGS);
    TSCADCIntStatusClear(SOC_ADC_TSC_0_REGS, status);

    if(status & TSCADC_END_OF_SEQUENCE_INT)
    {
         adc_read=true;
    }
    adc_isr=true;
}

Questions:
What are the possible reasons, such an ADC-FSM interrupt can not occure?
Is there a possibility the Sequencer FSM doesn´t start sometimes (besides it is already running)?

Sorry for the long post. In exchange here are some performance results i´ve optained with ADC-Measurement so far:

Sampling duration: 21 minutes
Sampling count: 78.750 million at 62500 Samples/s
Sampling method: sequenze of single (each channel measurements starts sequenzer FSM) singleshots for AN0 to AN6
identified wrong measurements: 0.048% because of timeout

Thank you for your attention. I hope someone can give me hints regarding my questions.


  •  Hi Martin,

    There are  16 steps in TSC/ADC controller. They are indexed from 0 to 15. To enable these steps StepEnable register is used.  Bitfiled to enable steps in step enable registers are indexed from 1 to 16. As a result of this, If one passes “stepSelct” argument as ‘1’ to   StepConfigure () API, then he is actually using step2. In order to enable step2 he has to ‘2’ as an argument to TSCADCConfigureStepEnable () API.

     In your code the function "StepConfigure(1, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL1+1); "  is selecting step2 to measure AN0 but enabling step1 instead of step2 in function "TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 1, 1);".This seems to be the problem.

    To enable step2 "TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 2, 1);".

        StepConfigure(1, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL1); // Configure step 1 for channel 1(AIN0)
        StepConfigure(2, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL2); //(AIN1)
        StepConfigure(3, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL3); //(AIN2)
        ...
        StepConfigure(7, TSCADC_FIFO_0, TSCADC_POSITIVE_INP_CHANNEL7); //(AIN6)

    Enabling the above configured steps,

    TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 2, 1);

     TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 3, 1);

      TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 4, 1); 

    TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 5, 1); 

      TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 6, 1);

    TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 7, 1);

    TSCADCConfigureStepEnable(SOC_ADC_TSC_0_REGS, 8, 1);

    Can you use above enabling step sequence to your configured steps. I hope this answers one of your questions

    Regards

    Savinay

  • Martin B��ckler said:

    Question:Is it possible that reading the Channel ID shifts the FIFO and the corresponding data is lost?

    NO..

     

  • Many thanks to Savinay Dharmappa regarding the configuration and activation of steps.

    Solution was implemented and works as intended.

    But it is still confusing to configure step 1 to 7, and activate them with selecting 2 to 8.

  • Savinay Dharmappa said:

    Question:Is it possible that reading the Channel ID shifts the FIFO and the corresponding data is lost?

    NO..

    [/quote]

    I did some further tests regarding this problem.

    Sorry, but i doubt your Answer. Reason:

    Using following testcode:

    //Test code
    int id = 0;
    int words = 0;

    //count words in FIFO + output
    words = TSCADCFIFOWordCountRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
    UARTPutNum(words);UARTPuts(" ",-1);

    //read channel ID + output
    id = TSCADCFIFOChannelIDRead (SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
    UARTPutNum(id);UARTPuts(" ",-1);

    //count words in FIFO + output
    words = TSCADCFIFOWordCountRead(SOC_ADC_TSC_0_REGS, TSCADC_FIFO_0);
    UARTPutNum(words);UARTPuts("\n",-1);
    //End of test

    Result of the testcode in console:

    1 4 0

    Interpretation:

    Before reading the ID, 1 Word stored in FIFO
    Sample belongs to Channel 4
    After reading the ID, 0 Words are stored in FIFO

    So, why does this happen? Let me suggest following:

    -ID is stored in the same register as ADC-Sample FIFO0DATA. ("spruh73c_.pdf", page 1573)
    -To know the ID,TSCADCFIFOChannelIDRead  reads the Register and returns ADCCHNLID. (I don´t know the underlying code.)
    -Reading the register triggers FIFO to shift to next sample, word counter is decremented by 1.
    ->ADC Sample is lost.

    Please correct me, if my suggestion is wrong.

    My solution will be:

    Reading the register FIFO0DATA once, split data into ADCCHNLID(Bit 16-19) and ADCDATA(Bit 0-11).

  • Hi Martin,

    Yes you are correct.

    Regards

    Savinay

  • Hey Martin,

    I have one question and I would be very grateful if you could answer.

    This is my situation: I have a BeagleBone Black connected with Code Composer Studio v5.5 through a JTAG, xds100v2. I'm using Starterware v02.00.01.01. The thing is, I want to use the analog inputs, and I really want to know if it is really possible to do it as you did on BeagleBone.

    I've already tested the gpioLEDBlink example and it is working correctly, so I already have perfect connection.

    The thing is, in the folder Starterware it only have ADC examples for evm335x and evmsk335x and I would like to be certain if I can get to work with the ADCs using Starterware on BBB. I've already tried adcVoltMeasure.c code from the folder evm335x, but I can't do the ADC inputs initialization because it can't run the function ADCConfigure(), where are present these 2 functions: TSCADCModuleClkConfig() and TSCADCPinMuxSetUp().

    So, I want to know if there is a way to work with ADC inputs on BBB using StarterWare doing a different initialization, or you could show me how you did it.

    Thanks for you attention.

    Best Regards,
    Luciano.
  • Hey,

    Just to say I found the answer: e2e.ti.com/.../1491789.

    BR,
    Luciano.