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.

MSP430G2203PW20: REN disables SPI SOMI at P1.6 in slave mode

Other Parts Discussed in Thread: MSP430G2203, MSP430G2553

Hi TI-Team,

During my programming on SPI communication I detected something strange. An enabled pull up/down functionality disables SPI output of slave. In this case if P1REN Bit 6 is set no data are sent from UCB0 on SOMI port. On pull up the other side receives 0xff. On pull down it receives 0x00. If P1REN Bit 6 is disabled then data are received on the other side.

For your background: SPI is enabled on a P1 edge interrupt as several MSP430G2203 communicate over the same line. To avoid an open line I intended to use REN to give it a defined value. Here is my code for SPI enable:

UCB0CTL1 |= UCSWRST;
P1SEL |= (BIT5 +BIT6 + BIT7); //Enable Ports
P1SEL2 |= (BIT5 +BIT6 + BIT7);
/*
 * Control Register 0
 *
 * ~UCCKPH -- Data is changed on the first UCLK edge and captured on the following edge
 * ~UCCKPL -- Inactive state is low
 * UCMSB -- MSB first
 * ~UC7BIT -- 8-bit
 * ~UCMST -- Slave mode
 * UCMODE_0 -- 3-Pin SPI
 * UCSYNC -- Synchronous Mode
 *
 * Note: ~<BIT> indicates that <BIT> has value zero
 */
UCB0CTL0 = UCMSB + UCMODE_0 + UCSYNC;
/*
 * Control Register 1
 *
 * UCSSEL_2 -- SMCLK
 * UCSWRST -- Enabled. USCI logic held in reset state
 */
UCB0CTL1 = UCSSEL_2 + UCSWRST;

 

/* Enable USCI */
UCB0CTL1 &= ~UCSWRST;
UCB0TXBUF = 0x5a;

 

IFG2 &= ~(UCB0RXIFG);   //enable SPI RX interrupt
IE2 |= UCB0RXIE;

 

If you find a mistake in my code please let me know. By the way I scanned family datasheet and errata sheet and did not detect any hint into this direction.

Regards

Guenther

  • In the posted code I can't see the P1REN being set. The posted code looks to be generated by Grace.

    When P1REN is set, does Grace force the port to be I/O rather than driven from the USCI (which sounds like the problem)?

    Can you post the code when P1REN is set and the problem occurs?

  • Hello Chester,

    I used Grace (by the way a great tool) to generate SPI initialization part and then I copied it into my P1 interrupt routine.

    The P1 initialization is also a copy from autogenerated Grace source. In my final project I do not use Grace as it conflicts with C++.

    Here is the initialization code:

    void GPIO_init(void)
    {
        /* Port 1 Output Register */
        P1OUT = 0; // BIT6;

        /* Port 1 Port Select Register */
        P1SEL = BIT4;

        /* Port 1 Port Select 2 Register */
        P1SEL2 = 0;

        /* Port 1 Direction Register */
        P1DIR = BIT0 +BIT1+ BIT4;

        /* Port 1 Resistor Enable Register */
        P1REN = BIT3 +BIT6;

        /* Port 1 Interrupt Edge Select Register */
        P1IES = 0;

        /* Port 1 Interrupt Flag Register */
        P1IFG = 0;

        /* Port 2 Output Register */
        P2OUT = BIT7;

        /* Port 2 Port Select Register */
        P2SEL = BIT1 + BIT4 + BIT6;

        /* Port 2 Port Select Register */
        P2SEL &= ~(BIT7);

        /* Port 2 Direction Register */
        P2DIR = BIT1 + BIT2 + BIT3 + BIT5 + BIT6 + BIT7;

        /* Port 2 Interrupt Edge Select Register */
        P2IES = 0;

        /* Port 2 Interrupt Flag Register */
        P2IFG = 0;

    }

    Regards
    Guenther

    PS: P1 Interrupt routine is inititialized later on.

  • From Table 19. Port P1 (P1.5 to P1.7) Pin Functions in the MSP430G2203 datasheet, for pin 1.6 to be the UCB0SOMI function, P1SEL.6 and P1SEL2.6 need to be one.

    Guenther Klenner said:
    Here is the initialization code:

        /* Port 1 Port Select Register */
        P1SEL = BIT4;

        /* Port 1 Port Select 2 Register */
        P1SEL2 = 0;

    The above code sets P1SEL.6 to zero and and P1SEL2.6 to zero. This will set pin 1.6 as an IO rather than SOMI.

  • Hi Chester,

    Yes, this is correct. In order to avoid any impact to SPI communication of other clients all SPI ports are selected as inputs until this client is addressed. I would liked to use 4pin SPI but P1.4 = UCB0STE is needed for a different purpose. So I had to make my own SPI enable functionality.

    You can see P1SEL.6 and P1SEL2.6 is set in the first code from top.

    Regards
    Guenther

  • Guenther Klenner said:
    I would liked to use 4pin SPI but P1.4 = UCB0STE is needed for a different purpose. So I had to make my own SPI enable functionality.

    How much time does the SPI master allow for the software in the SPI slave to change P1.6 from an input to SOMI?

    Looking at the MSP430G2203 datasheet pin schematics I can't see why setting REN would prevent P1.6 from acting as SOMI, so wondering if there is a timing problem.

    Also, had I2C been considered, since I2C allows multiple slaves to be addressed without having to change pins between I/O and USCI modules?

  • Hi Chester,
    I allow 1 ms to switch. If I remove setting of REN bit everything works fine. Just when it is enabled then I can not send data back to master.

    Yes, I have not found an indication either. That is why I raised this question.

    Yes, I use I2C on the same board at the other side of my master. I selected SPI as it requires less code (remember 2K FLASH and 256 Byte RAM) and does bi-direction at same time.

    Regards
    Guenther

  • I see the same behaviour with a MSP430G2553. With SPI in master mode, enabling the pull-up/pull-down resistor on the MOSI port prevents SPI from transmitting. My code is:

    ;; SPI mode

    mov.b #1,&UCA0CTL1 ; reset

    mov.b #0x09,&UCA0CTL0 ; master mode, synchronous

    bis.b #0x80,&UCA0CTL1 ; SMCLK

    mov.b #0,&UCA0BR0 ; clear divider

    mov.b #0,&UCA0BR1

    ;; SPI pin functions: MOSI is p1.2, don't care about MISO/SCK for now

    bis.b #BIT2,&P1DIR

    bis.b #BIT2,&P1SEL

    bis.b #BIT2,&P1SEL2

    ;bis.b #BIT2,&P1REN ; UNCOMMENT THIS LINE to break SPI.

    bis.b #BIT2,&P1OUT ; Bring out of reset

    bic.b #0x1,&UCA0CTL1

    In the code, writes are triggered by

    mov.b #0x55, &UCA0TXBUF

    It would be nice to know how to reconcile this with the port schematics (slas735f, pg. 42).

  • This is indeed strange. After digging through the port pin schematics, I don't see why the pullups will block SPI transfer. If you configure the port for use of pulldown, this will block I2C transfer - if the weak pulldown can fight the usually much stronger pullups on the bus).

    But in SPI mode, the output is active and should be able to override the pullup/pulldown easily, only leading to increased current consumption, bot not to data corruption/inhibition.

    So the observed behavior cannot be explained with the published port pins schematics.

    This is definitely a job for the TI engineers.

  • Not sure if it is related, but another anomaly I have noticed with a MSP430G2553 is that once UCB0 has been configured for I2C operation on P1.7 (SDA) and P1.6 (SCL) that P1IN reports bits 7 and 6 as zero rather than the actual input levels at the pins.

    Based upon the published port pins schematics in SLAS735G I would have expected the P1IN register to reflect the input to the UCB0 module.

  • I may be wrong, but my impression of the port pin schematics is that they are far from accurate. I also think that REN can only be used when a pin is a GPIO input.

  • OCY said:
    my impression of the port pin schematics is that they are far from accurate

    Too true too often :(

    OCY said:
    I also think that REN can only be used when a pin is a GPIO input

    This is different for different MSPs. True for most 5x devices, but on many 2x devices, it is possible. (so you could use the pullup in I2C mode - if it weren't so weak)

**Attention** This is a public forum