chipKIT® Development Platform

Inspired by Arduino™

Issues with SPI3 and interrupts

Created Sun, 07 May 2017 11:42:55 +0000 by GrahamM242


GrahamM242

Sun, 07 May 2017 11:42:55 +0000

Hi all,

I am attempting to utilise SPI3 on a Fubarino SD (1.5). I'm attempting to do back to back transfers (as I'm trying to interface a digital microphone), so I'm not using DSPI. Additionally, DSPI only seems to support a single SPI port on the Fubarino despite it having 4. My simple example code doesn't seem to fire off an interrupt, and I'm a little clueless as to why not.

What I've attempted to do is to set up an ISR that simply pushes more data when the SPI3 Transfer Done interrupt fires. I configure interrupts, configure SPI3 and then manually transmit a byte to get transmit happening. I can see that the byte is clocked out on an oscilloscope, but the interrupt doesn't get fired, so no more data comes out.

Any suggestions?

The reduced code looks like:

void __USER_ISR SPI3Isr(void) {
  uint32_t data;
  
  data = SPI3BUF;     // Read data as if we cared
  SPI3BUF = 0x00;     // More data to keep TX flowing
  clearIntFlag(_SPI3_TX_IRQ);
}

void setup() {
  pinMode(PIN_LED1,OUTPUT);

  SPI3CON = 0;                // Stop/reset SPI
  uint32_t rData = SPI3BUF;   // Clear RX buffer

  //Set interrupt vector
  setIntVector(_SPI_3_VECTOR, SPI3Isr);
  
  // Set interrupt priority
  setIntPriority(_SPI3_TX_IRQ, 4, 0);
  
  // Enable interrupt
  //clearIntFlag(_SPI3_TX_IRQ);
  setIntEnable(_SPI3_TX_IRQ);

  SPI3BRG = 500;       // Set speed to something
  SPI3STATCLR = 0x40;  // Ensure overflow is cleared
  SPI3CON = 0x8220;    // SPI on, 8 bits, SMP=1, Master mode
  
  SPI3BUF = 0x00;      // start tx/interrupts
}

void loop() {
  static uint32_t nextTime = 0;
  if (millis() > nextTime) {    // Aliveness test
    digitalWrite(PIN_LED1,!digitalRead(PIN_LED1));
    nextTime = millis()+200;
  }
}

majenko

Sun, 07 May 2017 13:12:02 +0000

Aha, you have fallen foul of something I whinged about ages and ages ago and a trap I still fall into repeatedly.

The function

setIntPriority(_SPI3_TX_IRQ, 4, 0);

is badly named. It should really be called something like setVectorPriority, since it operates on a vector not an IRQ number. Not a problem for the MZ chips where there is no IRQ / Vector differentiation, but on everything else it's a bit of a misnomer.

Changing to

setIntPriority(_SPI_3_VECTOR, 4, 0);

should fix it. [attachment=0]working.jpg[/attachment]

For audio work though it's better to use one of the newer chips - an MX370/470 for example, or an MZ. These have a REFCLKO (or a number of them) that are good for generating the master clock, which can also be the input clock to the SPI peripheral for a properly synchronised clock system for a CODEC chip (or other similar device) that uses (for example) I2S as its interface.

Also using DMA with a ping-pong buffer will give even smoother transfers.

I wrote this with the MZ parts in mind, and it's output only, but it may give you some pointers to the DMA usage.


GrahamM242

Sun, 07 May 2017 19:45:22 +0000

Of course, of course! I'd even looked at the interrupt controller for the MX7xx series and seen that there's just the single vector for the three interrupts. I'd just not realised that I should be setting the priority against the vector, not the interrupt source. And, when I put it like that it seems obvious! Thank you for the pointers!

Thanks for the tips on the MX370/MX470 series. At the moment, I'm just playing with a digital microphone that provides a pulse density modulation (PDM) output to represent the analog input. My plan is to use a cascaded integrator-comb CIC filter to convert that PDM signal into a more traditional PCM value (because this is what people who seem to know what they're talking about suggest). Having never had any experience with this, I don't know how successful I will be.


EmbeddedMan

Mon, 08 May 2017 14:01:44 +0000

GrahmM242-

Wow, you are correct. After looking into it, I realize that we don't have all three SPI ports exposed for FubarinoSD v1.5. This is a major oversight, and I will correct it shortly. (Note that there are only 3 SPI ports on the PIC32MX795F512H package that we use for the Fubarino SD, not four like with the larger packages.)

*Brian


EmbeddedMan

Wed, 10 May 2017 21:38:48 +0000

Full DSPI support has now been added to Fubarino SD, for all 3 SPI ports. I also added two DSPI example sketches (one with interrupts, one without). These will be available in the next version of chipKIT-core (whatever comes after v1.4.1) or you can get the files here:

https://github.com/chipKIT32/chipKIT-core/pull/348/files

and here:

https://github.com/chipKIT32/chipKIT-core/pull/350/files

*Brian


GrahamM242

Tue, 23 May 2017 15:55:07 +0000

Thanks Brian - I'll give that a go in due course.