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.

MSP430 Dysfunctional Interrupts General Question

Other Parts Discussed in Thread: MSP430FR5739

Hey! So I'm continuing from this post, and I need some feedback on what could cause an interrupt to not work as it should.  For some more information regarding my project, I'm working with the SPI module on the MSP430FR5739
.

So far, I know that in order to enable the interrupt, I have to set the interrupt enabler in its specified register.  I know that I have to do this after I set the other settings for the module, and when I enable the module.  Once I do this, I have to create an ISR, which can look something like this:

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
	while(~(UCA0IFG & UCTXIFG));
	UCA0TXBUF = transmitData;
	receiveData = UCA0TXBUF;
	transmitData++;
}

// trap isr assignation - put all unused ISR vector here
#pragma vector = ADC10_VECTOR, PORT2_VECTOR, PORT1_VECTOR,\
	TIMER0_A0_VECTOR, TIMER0_A1_VECTOR, WDT_VECTOR, COMP_D_VECTOR, \
	DMA_VECTOR,	PORT3_VECTOR, PORT4_VECTOR, RTC_VECTOR, \
	SYSNMI_VECTOR, TIMER0_B0_VECTOR, TIMER0_B1_VECTOR, \
	TIMER1_A0_VECTOR, TIMER1_A1_VECTOR, TIMER1_B0_VECTOR, \
	TIMER1_B1_VECTOR, TIMER2_B0_VECTOR, TIMER2_B1_VECTOR, \
	UNMI_VECTOR, USCI_A1_VECTOR, USCI_B0_VECTOR
__interrupt void TrapIsr(void)
{
  // this is a trap ISR - check for the interrupt cause here by
  // checking the interrupt flags, if necessary also clear the interrupt
  // flag
}

I've also added a trap ISR, in case other ISR are called by accident.  I'm not sure if I have to clear the interrupt flag inside the ISR, or if the system does it itself. Either way, I don't understand why an interrupt would not be called when all the initializing steps have been called.  Please let me know if I'm missing something to do with these interrupts.  Thanks

  • Normally, your ISR should look something like this:

    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    {
       switch ( __even_in_range( UCA0IV, 4 ) )
       {
          case 2:
             receiveData = UCA0RXBUF;
             break;
          
          case 4:
             UCA0TXBUF = transmitData++;
             break;
          
          default:
             break;
       }
    }

    There should be no reason to loop on the IFG flags - this can hang your program if the reason for the ISR is something other than the TX interrupt.

    Basically, the interrupt can get called for either a receive event or a transmit event. Using the IV register gets you the correct reason for the ISR being called so you can do the appropriate action.

    If you want to use the IFG flags, then check them independently (and don't wait on them). Also remember that if you go this route, you must clear the flags manually in your code. (Using IV clears automatically)

    The __even_in_range() intrinsic helps compiler generate efficient code. You should read up on how it works.

  • Thank you Brian.  I did put the more efficient ISR into my code, so that it can easily differentiate between a transmit and receive interrupt.

    However, the main problem I'm running into is that the ISR is not getting called all the time. Along with that, it isn't transmitting any of the characters back (even though I am putting data into the TX Buffer), nor is the data going to the MSP430 being saved in the receivedData buffer.

    I'm still wondering what would cause the ISR to not respond.  I'd expect it when the SPI sees data come into the RX Buffer, or when the TX Buffer has been loaded.  The problem I'm facing is not only does the ISR become enabled, but it doesn't even do what it's supposed to do.  What other suggestions could be given in figuring this out?

    ________________

    Update: I'm moving this question to another discussion.  The problem is that the SPI is not properly triggering teh ISR at all times, nor is it sending the right data when it has the opportunity to do so.  The link to the next post is here. For now, Thank you again Brian for the advice.

  • Did you globally enable interrupts (set the GIE bit)? If not, no ISR is ever called.
    Is your baudrate correct and did you properly configure the port pins? Are the incoming signals TTL level and not RS232 level? If one of the three is false, you’re probably never getting an RX interrupt. TX should work, though.

  • Jens-Michael Gross said:
    Did you globally enable interrupts (set the GIE bit)? If not, no ISR is ever called.

    I did enable the interrupts after I initialize all the peripherals I needed, using __bis_SR_register(GIE);

    Jens-Michael Gross said:
    Are the incoming signals TTL level and not RS232 level

    I admittedly had to look the differences between TTL and RS-232 up, and by seeing the explanation here, I believe the incoming signals are TTL.  I wasn't aware that RS-232 signals could be used outside UART, or even attempted through SPI, but it's good to check.

    Jens-Michael Gross said:
    did you properly configure the port pins

    I believe I did.  Below is the setup of the GPIO pins for the SPI module

    // Configure SPI Pins
    // Pin 1.5 set for Serial Clock Out (UCA0CLK)
    // Pin 1.4 set for SS (Slave Select) (UCA0STE)
    P1SEL1 |= SPI_CLK + SPI_SS;
    P1OUT &= ~(STROBE1 + STROBE2 + STROBE3 + STROBE4);
    P1DIR |= STROBE1 + STROBE2 + STROBE3 + STROBE4;
    
    // Terminate Unused GPIOs
    // P1.0 - P1.6 is unused
    P1OUT &= ~(BIT6 + BIT7);
    P1DIR &= ~(BIT6 + BIT7);
    P1REN |= (BIT6 + BIT7);
    
    // Configure SPI pins P2.0 and P2.1
    // Pin 2.0 set for Data Out (UCA0SIMO) (Output)
    // Pin 2.1 set for Data In (UCA0SOMI)
    P2SEL1 |= MOSI + MISO;
    P2DIR |= MISO;

    I have to admit that I don't think that I need to set the MISO pin as an output, since the Secondary module function is already selected for the pin.  However, this doesn't seem to change the way the MSP430 functions when I remove it.

    Jens-Michael Gross said:
    Is your baudrate correct

    I wasn't really sure how to set this, to be honest.  Since the datasheet states that if the MSP430 is set for Slave Mode, then UCxCLK is always used in slave mode.  I can see that the clock is running at 500kHz, but I'm not sure what baud rate to set it as.  I've also set the MSP430 to run at 24MHz.  I've tried to divide it by 48 (24MHz/48 = 500kHz) with no changes made to the functionality of the MSP430.  I've also set the eUSCI_Ax Modulation Control Word Register to 0, so that no added modulation occurs.  I'm really puzzled by how I should set the baud rate for this, and this confusion has led me to believe that this could be the cause to all of my problems.


    Please let me know how I should set the baud rate, given the SPI master is running their SPI clock at 500kHz, and my MSP430 clock running at 24MHz. 

  • Sorry, I overlooked the ‘SPI’ in the first post. And you didn’t post the configuration, so I (wrongly) assumed UART operation. For UART mode, it is a rather common mistake to be ignorant of the different signal levels. So I mentioned this. Of course, SPI usually doesn’t use RS232 signal levels. (While this can surely be done to improve signal quality for longer distances)
    For the same reason, please forget my question about the baudrate. In SPI mode, the baudrate is widely unimportant (even though it might be too high for the cable or the slave). The master provides the SPI clock and the slave works with it.

    Your description of your baudrate configuration sounds good. If SMCLK is 24MHz and UCA0BR is 48, then the SPI clock should be 500kHz, which should be acceptable for any slave. If running the USCI as SPI slave, then the clock is already coming in from the master, and you can only take it and hope it isn’t too fast for your code :)

     Now that I mentioned the missing init code: do you set the TXIE and RXIE bits after clearing SWRST? While SWRST is set, these bits are locked to 0.

     Note that UCA0STE has no meaning if the USCI is master. It doesn’t automatically select the slave or so. It is only an input for slave mode or if in multi-master mode. If you are master and want to talk to a slave, then you’ll have to provide the salve select by a GPIO pin. As there can be many slaves on the same bus, and the USCI cannot know which one you want to talk to.

     And you’re right, the USCI controls the direction of its pins depending on its current configuration. So for all USCI signals, the port pin direction register is ignored.

  • Jens-Michael Gross said:
    For the same reason, please forget my question about the baudrate. In SPI mode, the baudrate is widely unimportant (even though it might be too high for the cable or the slave). The master provides the SPI clock and the slave works with it.

    Thank you for the clarification.  It's good to know that the way I set the baud rate won't affect the program for my MSP430 SPI slave.

    Jens-Michael Gross said:
    do you set the TXIE and RXIE bits after clearing SWRST?

    Yup.  I wrote my code in reference to the datasheet and the example code. 

    Jens-Michael Gross said:
    Note that UCA0STE has no meaning if the USCI is master.

    The MSP430 code is configured as a SPI Slave device.  I also see the SPI Master pull down the SS pin when attempting to communicate to the SPI slave. 

    Check out the post I made in this discussion.  I've posted the code for how I initialize the SPI, as well as how the MSP430 is responding.  In short the MSP430 is going into the RX interrupt, but after 8 whole transmissions.  It seems like the SPI Module is being triggered, but it isn't seeing the whole clock.  I suspect that the clock speed from the master is too fast for the MSP430 SPI slave module to respond.  Let me know what you think

**Attention** This is a public forum