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.

MSP430FR2355: SPI

Part Number: MSP430FR2355


Tool/software:

Hi,

           I am using MSP430FR2355 controller for my project, i want to use SPI communication on this. I tried lot but i am unable to get success. My controller need to be act as Master only data transfer(no need to receive data).

I want to use port pins: 12,13,14 for SPI communication(UCB1)

Here is my code,

void spi_init()
{
P4SEL0 |= BIT5| BIT6 | BIT7; 

//Clock Polarity: The inactive state is high
//MSB First, 8-bit, Master, 3-pin mode, Synchronous
UCB1CTLW0 = UCSWRST; // **Put state machine in reset**
UCB1CTLW0 |= UCCKPL | UCMSB | UCSYNC
| UCMST | UCSSEL__SMCLK; // 3-pin, 8-bit SPI Slave
UCB1BRW = 0x20;
//UCB1MCTLW = 0;
UCB1CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
UCB1IE |= UCRXIE; // Enable USCI0 RX interrupt


}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCB1IV,USCI_SPI_UCTXIFG))
   {
       case USCI_NONE: break; // Vector 0 - no interrupt
       case USCI_SPI_UCRXIFG:
        UCB1IFG &= ~UCRXIFG;

       break;
      case USCI_SPI_UCTXIFG:
          if(SPI_byte_ptr < SPI_no_of_bytes)
           {

                   UCB1TXBUF = SPI_buffer[SPI_byte_ptr++]; // Transmit characters
                  UCB1IE |= UCTXIE;
           }
           else

          {
              UCB1IE &= ~UCTXIE;
              UCB1IFG &= ~UCTXIFG;

            }

         break;
        default: break;
    }
}

 While first time execute the code the interrupt will works after that, interrupt will not work.

while watching on the oscilloscope, there is no data transmission was happening, but CLK pin high state continuously.

Help to come out for this.

BR,

Yuvaraj V

  • The code that starts a transfer is missing but a couple of thoughts:

    1) There is no need for the receive interrupt or reading RXBUF if you don't care about that data. Ignore it.

    2) Setting TXIE within the ISR. What is that supposed to do? To execute that code TXIE must already be set.

    3) The way you end a transfer is a problem. The way it should be done is after writing the final byte to TXBUF, clear TXIE. Do not wait for the next transmit interrupt. That way the next time you start a transfer, TXIFG is set so that when you set TXIE there is an immediate interrupt. If TXIFG is clear, no interrupt.

  • Hi, 

    I am tried with the suggestions, but still i am facing same issue.

    the interrupt was generating only first byte transfer after initializing, after that interrupt not working also the data was transferring outside while i am seeing port pin status on oscilloscope.

    My updated code is below:

    void spi_init()
    {
    P4SEL0 |= (BIT5| BIT6 | BIT7); // set 3-SPI pin as second function

    //Clock Polarity: The inactive state is high
    //MSB First, 8-bit, Master, 3-pin mode, Synchronous
    UCB1CTLW0 = UCSWRST; // **Put state machine in reset**
    UCB1CTLW0 |= UCCKPL | UCMSB | UCSYNC | UCMST | UCSSEL__SMCLK; // 3-pin, 8-bit SPI Slave
    UCB1BRW = 0x20;
    UCB1CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch(__even_in_range(UCB1IV,USCI_SPI_UCTXIFG))
    {
    case USCI_NONE: break; // Vector 0 - no interrupt
    case USCI_SPI_UCRXIFG:
    UCB1IFG &= ~UCRXIFG;
    break;

    case USCI_SPI_UCTXIFG:
    if(SPI_byte_ptr < SPI_no_of_bytes)
    {
    UCB1TXBUF = SPI_buffer[SPI_byte_ptr++]; // Transmit characters

    }
    else
    {
    UCB1IE &= ~UCTXIE;
    }
    UCB1IFG &= ~UCRXIFG;
    UCB1IFG &= ~UCTXIFG;
    break;
    default: break;
    }
    }

    int main(void)
    {
    init();
    adc_config();

    delay(500);

    TB0CCTL0 |= CCIE; //Compare mode
    TB0CTL |= TBSSEL_2 | MC_1 | ID_3; //General timer
    TB0CCR0 = 2000;
    delay(500);

    while(1)
    {

         if(SPI_update_flag)    //SPI Flag will set for every one seconds once.
        {
              SPI_buffer[0] = 0x11;
              SPI_buffer[1] = 0x0A;
              SPI_buffer[2] = 0x04;
              SPI_update_flag = 0;
              SPI_byte_ptr = 0;
              SPI_no_of_bytes = 3;


              UCB1IE |= UCTXIE;
         }

    }

  • I am tried with the suggestions, but still i am facing same issue.

    No, you didn't. You made it worse. Consider what happens after setting TXIE. (I have to assume that GIE is set but you don't show that.) The transmit data interrupt triggers and the ISR starts. It writes a byte to TXBUF, clearing TXIFG. But the transmit shift register is empty so this gets transferred into the shift register immediately. Setting TXIFG. Then you clear TXIFG before exiting the ISR. No more transmit interrupts.

    Please use the "Insert: code" feature of the editor when posting code. 

**Attention** This is a public forum