0

For educational purpose (I'm new in this area), I'm trying to write a driver for the AD7124 ADC, connected to the SPI serial interface of a Raspberry PI4, running under Raspbian with a kernel v5.4 on which I applied a RT patch.

This ADC has a continuous read mode in which the readiness of a new sample is signalled by the lowering its (DOUT/!RDY) pin.

In addition to it being connected to the MISO pin, my idea was to connect it to a GPIO pin of the Raspi, in order to raise an interrupt for each new sample, triggered by the lowering of the DOUT/!RDY pin.

The issue is that the SPI read done in my interrupt fires a new interrupt, as seen in the capture from an oscilloscope (https://i.stack.imgur.com/BJnbO.png), connected to the DOUT/!RDY pin (in yellow), and the clock signal of the SPI interface (in purple). The SCLK signal is triggered by the SPI read, and we can see that two reads are triggered for only one ready sample.

Below, how I request the IRQ in the probe proc :

    // Getting the interrupt GPIO pin
    padpvd->pgpio_desc = devm_gpiod_get (&spi->dev, AD7124_GPIO_NAME, GPIOD_IN ) ; 
    if (IS_ERR(padpvd->pgpio_desc)) {
      ...
    }   
    // Getting the interrupt number
    padpvd->irq = gpiod_to_irq(padpvd->pgpio_desc);
    if (padpvd->irq < 0) {
      ...
    }   

In an IOCTL start routine, after having started the ADC, I request the IRQ :

    ret = request_threaded_irq ( padpvd->irq, NULL, ad7124_threaded_irq_handler,
                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                 THIS_MODULE->name, padpvd->ad7124_spi_dev ) ;

In the handler, I do not do much more than reading the data using an spi_sync() call, and storing it in a buffer, before returning IRQ_HANDLED.

So the question is: why do the signals generated on my GPIO PIN by the SPI transfer fire an interrupt while I used the IRQF_ONESHOT flag ?

0andriy
  • 4,183
  • 1
  • 24
  • 37
Fabien
  • 1
  • 1
  • Nobody forbids you to look into existing driver code (power of OSS!): https://elixir.bootlin.com/linux/latest/source/drivers/iio/adc/ad7124.c – 0andriy Oct 29 '20 at 17:52
  • 1
    That was not the answer I expected but it did help me as I found what I missed: the use of the functions disable_irq_sync / enable_irq. I had tried disable_irq, but with no success. So thank you. – Fabien Oct 30 '20 at 17:11
  • 1
    Create your own answer, everybody will benefit out of it! – 0andriy Oct 30 '20 at 19:56
  • Yes I'll do that when I have understood why the IRQ are fired despite the IRQF_ONESHOT flag being used. – Fabien Nov 01 '20 at 10:11

0 Answers0