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 port mapping

Other Parts Discussed in Thread: CC430F5137

Hello,

I am using the CC430F5137 for my project. The only problem i have is that i want to switch I2C between 2 pins.

SCL: P1.2            SDA: P1.3

to

SCL: P1.6           SDA: P1.7

I have to switch between the pins during runtime. Now i have the code to do that, but the I2C does not work on P1.6/P1.7.

Here is my Code:

void SwitchOnI2C_main()
{
   // enable high pin
   P3DIR |=  BIT0;
   P3SEL &= ~BIT0;
   P3OUT |= BIT0;

   P1SEL &=~(BIT3|BIT2);
   P1DIR |= (BIT3|BIT2);
   P1OUT |= (BIT3|BIT2);

   __disable_interrupt();

   // enable port mapping
   PMAPPWD = 0x02D52;  // Get write-access to port mapping regs
   PMAPCTL |= PMAPRECFG;
   P1MAP3 = PM_UCB0SDA;                      // Map UCB0SDA output to P1.3
   P1MAP2 = PM_UCB0SCL;                      // Map UCB0SCL output to P1.2
   PMAPPWD = 0;          // Lock port mapping registers

   __enable_interrupt();

   UCB0CTL1 |= UCSWRST;                      // Enable SW reset
   UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
   UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset

   UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
   UCB0IE   |= UCRXIE | UCTXIE | UCNACKIE;   // Enable RX and TX and NACK interrupts

   P1SEL |= BIT3 | BIT2;
}

and

void SwitchOffI2C_main()
{
   P3DIR |=  BIT0;          // output dir
   P3OUT |=  BIT0;          // set to 0
   P3SEL &= ~BIT0;

   __disable_interrupt();

   // enable port mapping
   PMAPPWD = 0x02D52; // Get write-access to port mapping regs
   PMAPCTL |= PMAPRECFG;
   P1MAP3 = PM_NONE;                      // remap
   P1MAP2 = PM_NONE;                    // remap
   PMAPPWD = 0;

   __enable_interrupt();

   P1SEL &= ~(BIT3 | BIT2); // no 2nd func
   P1DIR &= ~(BIT3 | BIT2); // output dir
   //P1OUT &= ~(BIT3 | BIT2); // set to 0
}

The code has the same functioniality for the other pin.

After switching the pin i want to ask if a slave is present like:

unsigned char TI_USCI_I2C_slave_present(unsigned char slave_address)
{
  unsigned char slaveadr_bak, ucb0ie_bak, returnValue=0;
 // unsigned char ie2_bak, slaveadr_bak, ucb0i2cie, returnValue;
  //ucb0i2cie = UCB0IE;                      // restore old UCB0I2CIE
  ucb0ie_bak = UCB0IE;                       // store IE2 register
  slaveadr_bak = UCB0I2CSA;                  // store old slave address
  UCB0IE &= ~ UCNACKIE;                      // no NACK interrupt
  UCB0I2CSA = slave_address;                 // set slave address
  UCB0IE &= ~(UCTXIE + UCRXIE);              // no RX or TX interrupts
  __disable_interrupt();
  UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP;      // I2C TX, start condition

  //while (UCB0CTL1 & UCTXSTP);              // wait 10 ms for STOP condition, otherwise: FALSE!
  int16_t count_ready = 10000;
  while (1)
  {
     if ((UCB0CTL1 & UCTXSTP) == 0)
     {
        returnValue = !(UCB0STAT & UCNACKIFG);
        break;
     }
     if (count_ready <= 1)
     {
        returnValue=0;
        break;
     }
     BSP_Delay(1);
     count_ready--;
  }


  __enable_interrupt();
  UCB0IE = ucb0ie_bak;                       // restore IE2
  UCB0I2CSA = slaveadr_bak;                  // restore old slave address
//  UCB0IE = ucb0i2cie;                      // restore old UCB0CTL1
  return returnValue;                        // return whether or not
                                             // a NACK occured
}

And everytime i get a answer that the slave is not present.

The I2C does not send a start condition or a stop condition. There is only a falling edge and then a rising edge and still keep high.
Can anyone help me to drive the I2C right?


Thanks,

Christof

  • You are saying that I²C on P1.6/P1.7 does not work. Why are you then showing everything except the code that configures P1.6/P1.7?
  • The configuration for P1.6 and P1.7 is the same.

    void SwitchOnI2C_second()
    {
    // enable high pin
    P2DIR |= BIT0;
    P2SEL &= ~BIT0;
    P2OUT |= BIT0;

    P1SEL &=~(BIT6|BIT7);
    P1DIR |= (BIT6|BIT7);
    P1OUT |= (BIT6|BIT7);

    __disable_interrupt();

    // enable port mapping
    PMAPPWD = 0x02D52; // Get write-access to port mapping regs
    PMAPCTL |= PMAPRECFG;
    P1MAP7 = PM_UCB0SDA; // Map UCB0SDA output to P1.7
    P1MAP6 = PM_UCB0SCL; // Map UCB0SCL output to P1.6
    PMAPPWD = 0; // Lock port mapping registers

    __enable_interrupt();

    P1SEL |= BIT6 | BIT7;
    }

    and

    void SwitchOffI2C_second()
    {
    P2DIR |= BIT0; // output dir
    P2OUT &= ~BIT0; // set to 0
    P2SEL &= ~BIT0; // no 2nd func

    __disable_interrupt();

    // enable port mapping
    PMAPPWD = 0x02D52; // Get write-access to port mapping regs
    PMAPCTL |= PMAPRECFG;
    P1MAP6 = PM_NONE; // remap
    P1MAP7 = PM_NONE; // remap
    PMAPPWD = 0;

    __enable_interrupt();

    P1SEL &= ~(BIT6 | BIT7); // no 2nd func
    P1DIR |= (BIT6 | BIT7); // output dir
    P1OUT &= ~(BIT6 | BIT7); // set to 0 (Test set to 1)
    }

    I have changed something in the code, but the I2C on P1.6/P1.7 does not work.
    It seems like that the bus does not send an start or a stop bit.
    The I2C on the other bus works perfect.

    Thanks and best regards,
    Christof
  • Hi Christof!

    Christof Schuetzenhoefer said:
    P1SEL &= ~(BIT6 | BIT7); // no 2nd func

    The port mapped function is the secondary function for the pin so the P1SEL bits must be set.

    Dennis

  • the P1SEL bits must be set

    The P1SEL bits are set at the end of the function.

    Christof, please check if the PMAPLOCKED bit is actually cleared.

  • Clemens Ladisch said:
    The P1SEL bits are set at the end of the function.

    Right, sorry, looked at the wrong function.

    Dennis

**Attention** This is a public forum