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.

Questions about Touchscreen / ADC subsystem

Expert 2280 points


Hi, I need some clarifications on how TSC_ADC_SS works.

Which is the size of FIFOs?

In figure 12-1 of TRM it seems 64 x 16 bit. I suppose that 12 bits are the sampled value and other 4 bits are for the id tag, therefore max 64 samples. But it happens that when I read FIFO0COUNT sometimes I get values grater than 64: how can it be? I've just configured a single step in sw-continuous mode to sample AIN0.

And what does happen when FIFO is full? Is the oldest value discarded and replaced by new sample?

I've set the out-of-range check in stepconfig, a max value in ADCRANGE register and enabled out-of-range IRQ. In the ISR, to get the value that causes the interrupt, do I have to read all the samples in the FIFO0 till the last one? Does the FIFO0DATA register work in a clear-on-read manner?

In the TRM I've found a little bit of confusion between concepts of "step" and "channel": "There are 16 programmable Step Configuration registers which are used by the sequencer to control which switches to turn on or off (inputs to the AFE), which channel to sample, and which mode to use". With "channel" do you mean the input (AIN0, AIN1, etc)? But the ID in FIFO0DATA registers seems to refer to the step more than the channel/input, even if it is described as "Optional ID tag of channel that captured the data".

Best regards,

Max






  • Max,

    As mentioned the size of each FIFO is 64 x 16 bit. I am not sure of how you are reading values greater than 64. Ideally when the FIFO is full, FIFO word count should read 64.  

    When FIFO is full, new samples replace the old ones, But along with this you should also observe a FIFO Overrun interrupt.

    Yes, FIFODATA register works in a clear-on-read manner. To get the value that causes out-of-range interrupt , reading the last data in FIFO would be sufficient.

    Yes,  "channel" in this context refers to analog inputs(AIN0-AIN8). When talking about FIFO0DATA register channels refer to "steps". This is the only place in TRM where it is interchanged.

     

    Regards,

    Rachna

  • Rachna, thanks for your answers.

    Rachna Patil said:
    I am not sure of how you are reading values greater than 64. Ideally when the FIFO is full, FIFO word count should read 64.
    When FIFO is full, new samples replace the old ones, But along with this you should also observe a FIFO Overrun interrupt.

    The max value I can read in FIFO0COUT register is 127. I've enabled FIFO0OVERRUN interrupt: in the ISR, when a FIFO0OVERRUN arises I read the FIFO0COUNT, but I get every time a different value in range 1-127.

    Rachna Patil said:
    Yes, FIFODATA register works in a clear-on-read manner. To get the value that causes out-of-range interrupt , reading the last data in FIFO would be sufficient.

    To do this, in the ISR, I read the FIFO0COUNT and then I read the FIFO0DATA for a number of times equal to the FIFO0COUNT value. Is it correct?

    But how does the ADC behave during the ISR? I suppose it is running continuously, so it could do new samples, changing FIFO0COUNT and FIFO values before my ISR can serve the interrupt and read the correct values. Isn't it or am i missing something?

    Do I need to take care of any time constraint in the ISR or in writing/reading registers? In your code of Touchscreen driver, there is a udelay(315) in the ISR: what is it used for? And which is the purpose of the IRQ_EOI register? I did not find any description in TRM.

    Finally, is there any simple way to read/write registers from userspace? I've tried to use /dev/mem with mmap, but seems not working always fine: I can read 0x47300001 at 0x44E0D000 (REVISION register), but not much more...

    Best regards,

    Max

  •  Max,

    Qmax said:
    To do this, in the ISR, I read the FIFO0COUNT and then I read the FIFO0DATA for a number of times equal to the FIFO0COUNT value. Is it correct?

    No, Here you are reading all values generated by the ADC up to now, which is not desired. You just want to know the value on which the out-of-range interrupt  has occurred. You can achieve this by reading the last value in the FIFO. Just one FIFO read inside the ISR will serve the purpose.

    Qmax said:
    But how does the ADC behave during the ISR? I suppose it is running continuously, so it could do new samples, changing FIFO0COUNT and FIFO values before my ISR can serve the interrupt and read the correct values. Isn't it or am i missing something?

    On receiving an interrupt I disable all the steps, This would not yield another interrupt. Meanwhile reading the FIFO would result  samples pertaining to this interrupt. At this point the sequencer would schedule all the steps enabled. Before leaving the ISR I re-enable the steps, dues to which next interrupt can be generated. Hence the FIFO count and FIFO values are not tampered.

    Qmax said:
    Do I need to take care of any time constraint in the ISR or in writing/reading registers? In your code of Touchscreen driver, there is a udelay(315) in the ISR: what is it used for? And which is the purpose of the IRQ_EOI register? I did not find any description in TRM.

    No, there is no necessity for extra care to be taken in accessing registers. By adding a delay in the code, I provide time for the sequencer to settle, So that correct state of the sequencer can be read. Based on this result i am making few decisions. IRQ_EOI is a different register namely "TSC_ADC_SS_IRQ_EOI" and not apart of IRQ registers.

    Qmax said:
    Finally, is there any simple way to read/write registers from userspace? I've tried to use /dev/mem with mmap, but seems not working always fine: I can read 0x47300001 at 0x44E0D000 (REVISION register), but not much more...

    You can use devmem2.

    Usage: devmem2 { address } [ type [ data ] ]

    address : memory address to act upon

    type : access operation type : [b]yte, [h]alfword, [w]ord

    data : data to be written

     

    Regards,

    Rachna

  • Hello Rachna mam,

                             I am using beaglebone black board with ubuntu 12.04.3 LTS. I have a edt-5.7"-wvga LCD with touch. Lcd is properly working with this setup. LCD touch is also working properly. But each time I need to calibrate for proper touch. Also I tried to stored values in /usr/share/X11/xorg.conf.d/10-evdev.conf  but after reboot I am getting lost of touch calibration. And after recalibration values of calibration also changing.
           I am getting following values after reboot:

                     Xmin    Xmax     Ymin     Ymax
                  1. 163     3941     238      3872
                  2. 97      4006      77      3850
                  3. 125     4046     308      4070
                  4. 84      3958     42       3909
                  5. 144     3957     88       3982
                  6. 51      3990     44       3804
                  7.-63      3834    -3        3803

       How can I resolve this problem??        

    Regards,

    Kishor Dhanawade.

  • Rachna,

    You mention about the udelay is added for the sequencer to settle, so that correct state of the sequencer can be read. Is it possible to remove the delay? Will it affect performance if putting udelay in the ISR?

    Regards,

    Kevin

  • Yes, using udelay() in interrupt will eat your cpu processing power.

    Check this post:

    http://e2e.ti.com/support/arm/sitara_arm/f/791/t/319613.aspx