STM32F103 - EXT triggering SPI read

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

Simon
Posts: 11
Joined: Sun Sep 28, 2014 11:45 pm
Has thanked: 1 time

STM32F103 - EXT triggering SPI read

Postby Simon » Mon Feb 13, 2017 11:47 pm

HI Guys,

I'm after a little guidance (or maybe a lot) I currently have an STM32F103VET interfacing to a AD7767 24bit ADC, so the current code that works by itself it uses the ext driver to trigger and interrupt on the falling edge of the DRDY pin (from the ADC). From the interrupt I can call a spiStartReceive (which I'm pretty sure Im not meant to do). Then have the SPI callback that casts the 24bit signed number into a 32bit signed and store is in a simple ring buffer (implemented my own as I didn't want any blocking). I then filter this in a normal thread.

This is works stand alone, but when I add the other parts of the project together which is are, GPT interrupt (2kHz at the moment), Timer capture event, a serial port (for GPS) and the USB serial output it all falls over.

Now I know this is because the callback is not finishing in time for the next interrupt Ive tired making as small as possible but not having much luck. All the other interput sources can wait a little the only other critical one is the time capture but as that is hardware I just need to get to it before the next event (every send it a GPS PPS).

Oh the AD7767 is outputting at 32kHz and I am using a digital isolator chip that has max through put of about 1Mhz so I cant just raise the SPI clock to get more time.

So back to the question, what is the best way to trigger the SPI from the ext interrupt. I need it to be quick without blocking cpu resources. Ive considered waking a thread from the interrupt and using a synchronous SPI, but not sure if that will respond quick enough, I really need this to take precedent over all other threads.

Thanks
Simon

Simon
Posts: 11
Joined: Sun Sep 28, 2014 11:45 pm
Has thanked: 1 time

Re: STM32F103 - EXT triggering SPI read

Postby Simon » Tue Feb 14, 2017 2:21 am

So after a bit of head scratching and getting my head around some ideas I have a solution that seems to be working

So when the EXT interrupt is triggered I wake a thread as per (http://www.chibios.org/dokuwiki/doku.ph ... tos:wakeup), the thread has an absolute priority has the following code;

Code: Select all

void SpiAdcThread() {

  while (true) {
 
    /* Waiting for the IRQ to happen.*/
    chSysLock();
    chThdSuspendS(&ADCtrp);
    chSysUnlock();
   
    /* Perform processing here.*/
    spiSelectI(&SPID1);
    spiReceive(&SPID1, 3, rxbuf);
   
    // Cast the 24bit signed number into a 32bit signed ready for averaging
    int32_t ADCword = (rxbuf[0]<<16)|(rxbuf[1]<<8)|(rxbuf[2]);
    if (ADCword & 0x00800000)
    {
      ADCword |=  0xFF000000;
    }
   
    putADCbuffer(ADCword);
  }
}


So far seems to be working well need to do some more tests to make sure I'm not dropping data. I'm also still keen to hear if any one has better suggestions for how to implement this.

Thanks
Simon

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: STM32F103 - EXT triggering SPI read

Postby Giovanni » Tue Feb 14, 2017 7:16 am

Hi,

You could do the callbacks dance.

1) From the EXT callback call spiSelect() then spiStartExchangeI() (enclosed in lock/unlock).
2) From the SPI callback call spiUnselect().

This way there is no thread, you save some memory and improve latency.

Make sure to enable assertions and state checker in chconf.h, those will find most common errors.

Giovanni

Simon
Posts: 11
Joined: Sun Sep 28, 2014 11:45 pm
Has thanked: 1 time

Re: STM32F103 - EXT triggering SPI read

Postby Simon » Tue Feb 14, 2017 12:51 pm

Thanks for the reply,

That was how my code was originally structured (I used SPIstartRead as i was only receiving) but I found it stopped working (EXT was triggering but the SPI callback wasn't and the SPI_CS stayed low) when I stressed the USB virtual serial (I'm outputting the ADC data in HEX to the serial console at 2kHz).

I'm not 100% around callbacks I assume they have highest priority, I also gather they have to wait until the processor is release from what ever thread is currently running.

Unfortunately I am working without the debugger but I am going to have to fix it as this project is getting bigger and I'm getting up to memory management. I originally started development on a stm32F103RB-NUCLEO but have now made my own hardware with a bigger processor (stm32F103VET) I did the whole copying of the project and changing the makefile and .project file before importing, and new board of course which has worked well but I do not have the debug options (been spoilt by chibio studio not having to set that up) to start with.

Thanks
Simon

Simon
Posts: 11
Joined: Sun Sep 28, 2014 11:45 pm
Has thanked: 1 time

Re: STM32F103 - EXT triggering SPI read

Postby Simon » Thu Feb 16, 2017 1:19 am

Hi Again,

I'm still having problems its working but missing every 3rd or 4th ADC read looking at the oscilloscope it seems it not finishing the last transfer in time.

so the blue trace is the DRDY line which I am triggering the EXTI from, the yellow line is the chip select (active low)
https://www.dropbox.com/s/b0jbyd4ppq0m8 ... 9.jpg?dl=0

zoomed in you can so see the delay from the DRDY (blue) to the CS line (yellow) going low.
https://www.dropbox.com/s/a5wy7bvlycwzk ... 9.jpg?dl=0

So what is happening my EXT interrupt simply wakes this thread

Code: Select all

void SpiAdcThread() {

  while (true) {
    /* Waiting for the IRQ to happen.*/
    chSysLock();
    chThdSuspendS(&ADCtrp);
    chSysUnlock();

    /* Perform processing here.*/
    spiSelect(&SPID1);
    spiReceive(&SPID1, 3, rxbuf);
    spiUnselect(&SPID1);
    // Cast the 24bit signed number into a 32bit signed ready for averaging
    int32_t ADCword = (rxbuf[0]<<16)|(rxbuf[1]<<8)|(rxbuf[2]);
    if (ADCword & 0x00800000)
    {
      ADCword |=  0xFF000000;
    }

    ADCFilterBuffer[ADCFilterIndex++] = ADCword;
    ADCFilterIndex &= 0x1F;
  }
}


but this thread does not always finish in time for the next interrupt so it missed (which you can see as the yellow line staying high on the oscilloscope).

So what I want to investigate is using fast interrupts to speed up the response, I have read the document on interrupts handling but I am unsure how to apply them to the EXT interrupt, and I have not been able to find any exampled of EXT and faster interrupts.

I am also calling a RT function from the interrupt.

Code: Select all

chThdResumeI(&ADCtrp, (msg_t)0);  /* Resuming the thread with message.*/

which I am assuming will also be a problem.

Any thoughts or suggestions.

I do have some other hardware fixes I could do, if I'm unable to find a software, I'm going to try a higher SPI speed but already at the limit of the digital isolator chip, I can also look at clocking the ADC at a lower frequency give me more time as it currently outputting data at 32kHz.

Thanks
Simon

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: STM32F103 - EXT triggering SPI read

Postby Giovanni » Thu Feb 16, 2017 9:03 am

Hi,

Try using a binary semaphore initialized to false instead of suspend/resume. It will buffer an event even if the SPI transfer is in progress.

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 16 guests