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.

MSP430F2012: SPI slave no interrupt?

Other Parts Discussed in Thread: MSP430F2012

Hi all,

I want to connect a Cortex-R4 RM48HDK development board (master) to a launchpad with a MSP430F2012 (slave) using SPI. When I transmit data from the master to the slave, I can correctly see those in USISR on the F2012. If I receive data afterwards without altering anything, I get my original values back at the master, which is what I expected. The problem is, no interrupt is triggered during all of this, even though the SPI interrupt is enabled in grace. If I manually set USIIFG to 1, an interrupt is triggered as expected. At startup, I did have to clear USIIFG manually before enabling interrupts, otherwise I would get flooded with false interrupts. 

I do not use CS, since only the devices mentioned are on the bus. I expected the interrupt to be triggered on the first incoming data edge, but apparently this is not the case. Am I missing something obvious?

Regards,

Tim

  • Update: I restored the original startup sequence, which automatically triggers a false irq, which leads to the irqs sometimes being triggered correctly and sometimes nothing happening. The strange thing is that the USISR value is always updated, but very often the interrupt just does not trigger. The interrupt routine just sets a flag and clears USIIFG, the rest is done in main(). The master clocks the spi at 250 kHz. Increasing the CPU speed from 1 MHz to 16 MHz did not have any effect.

    I'm at a loss, does anyone have a similar experience? 

  • Problem is that in slave mdoe, you don't have any control over teh receive process. The master sends and you have to be ready.

    Just clearing the RX IF Gbit and setting a flag is nonsense. You could as well discard the ISR and check for the IFG bit directly in main. Less code, some CPU cycles saved, same effect. And if the main code doesn't read the received value fast enough (and writes teh next byte to teh USI register) then you'll miss data.

    What the ISR should do:

    1) clear the IFG bit
    2) read the received data and store it in a buffer
    3) write the response (if any)
    4) notify main (this can be inplicitely be done by the receive buffer pointer - note that iut must be declared volatile, so main will notice the 'magic' background change)
    5) check whether the IFG bit is set again
    6) if so, loop to 1) (this saves the time for a superfluous ISR entry and exit)
    7) exit to main.

    Main then has all the time it needs to process the received data, while more is coming in in the background. Of course the buffe rmust be large enough and main must be fast enough in average so that the buffer doesn't overflow.

  • The problem is the ISR isn't called most of the time, even if the data come through correctly. The miniscule ISR is used to get the system out of low power mode. Will elaborate later.

    Edit: Thanks for your helpful response! You are certainly correct that I should check the interrupt flags itself instead of a custom flag. The sole purpose of the current ISR is to wake up the system and let it check what has been done. This is more or less like polling, except that it is possible to use low power states, in which the device will be 99+% of the time. I planned on implementing a custom lock system to detect missing data, since a hardware flag is set if data is overwritten without being read, but your idea seems better.

    This still does not solve the problem of the interrupt itself not triggering on correctly incoming data, however. Any ideas on that?

  • Tim Mulder said:
    This still does not solve the problem of the interrupt itself not triggering on correctly incoming data, however. Any ideas on that?

    The USI is really the wrost thing for SPI slave. It needs to be 'armed' (by setting a new bit count) for each transfer. If you don't tell it to receive the next byte before the master sends it, you might lose bits or even whole bytes.

    So worst case, you have less than 1/2 SPI clock pulse to read the last byte and rearm the USI.

    I never used the USI myself, so I migh tmiss something here, but from what I read, an USI based SPI slave requires very tight coding.

    BTW: you should use the CS signal anyway, as it alows you to synchronize the transfer in case of missed bits or catched superfluous clock pulses due to master port initialization.

    If CS is asserted, you know that a new transfer begins, at a new byte border. And when it is de-asserted, you knwo that the transfer has ended, whether you got all of it or missed some.

  • Just before you posted I found out myself, that I have to reset the counter to the amount of bits I want to be read next transfer.

    I will start using the CS for the purposes you mentioned, thanks for the tip!

     

     

**Attention** This is a public forum