Quantcast
Channel: MSP430 Technical Forums
Viewing all articles
Browse latest Browse all 2077

Issue with I2C SW Master and USI Slave

$
0
0
I want to pre-emptively thank anyone who takes a look at this. I have been lurking here a bit and have learned a great deal from you all. With that said, I am having an interesting issue while using TI reference code for a SW I2C Master and USI Slave. When I use the Master on a line with no slaves OR when I am using it to write to a TI DRV8830 Reference Kit. I can see the data flowing over the line and in the case of the TI DRV8830 I can see the ACKs and see my motor turn on. 

 

Screen Shot 2013-09-10 at 8.46.43 PM (2).png
 
 

However when I attempt to write to the USI Slave the timings are all off and very strange data is written out. 

 

Correct (with no slaves on the line hence the NACKs)

 

[0x90 0xA0 0x0fd0]

 

Screen Shot 2013-09-10 at 9.45.41 PM.png

 

 

 

Incorrect (with USI Slave Attached)

 

Screen Shot 2013-09-10 at 9.43.41 PM.png

 

It looks like something is getting messed up when the USI Slave is sending the ACK and holding SDA low but I cannot for the life of me figure out what it happening. 

 

These are both MSP430G2231's running on Launchpads. The Masters are running on buses on a breadboard with 10K Pull-up resistors to VCC on the Launchpads. I believe the issue is in the state machine for the receive code and specifically when the code grabs data and ACKs below is just that snippet. 

 

Below will be my code for the USI Slave (mostly in the USI_TXRX intertupt routine) and the Master. 

 

 

#pragma vector = USI_VECTOR

__interrupt void USI_TXRX (void)

{

  if (USICTL1 & USISTTIFG)             // Start entry?

  {

    P1OUT |= 0x01;                     // LED on: sequence start

    I2C_State = 2;                     // Enter 1st state on start

                                       //READ_ADDR = I2C_State;

  }

 

  switch(I2C_State)

    {

      case 0: // Idle, should not get here

              break;

 

      case 2: // RX Address

              USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, RX address

              USICTL1 &= ~USISTTIFG;   // Clear start flag

              I2C_State = 4;           // Go to next state: check address

                                       //READ_ADDR = I2C_State;

              break;

 

      case 4: // Process Address and send (N)Ack

            

            

            //READ_ADDR = USISRL;

            

              /*if (USISRL & 0x01)       // If read...

              {

                SLV_Addr++;            // Save R/W bit

              }*/

              USICTL0 |= USIOE;        // SDA = output

                                       //READ_ADDR = USISRL;

                                       //READ_ADDR1 = SLV_Addr;

            

              if (USISRL == SLV_Addr)  // Address match?

              {

                USISRL = 0x00;         // Send Ack

                P1OUT &= ~0x01;        // LED off

                I2C_State = 8;         // Go to next state: RX data

                                       //READ_ADDR = 0xAA;

                  

              }

              else

              {

                  //READ_ADDR = 0xAB;

                USISRL = 0xFF;         // Send NAck

                P1OUT |= 0x01;         // LED on: error

                I2C_State = 6;         // Go to next state: prep for next Start

              }

              USICNT |= 0x01;          // Bit counter = 1, send (N)Ack bit

            

            //I2C_Send_Data();

                

           

              break;

 

      case 6: // Prep for Start condition

              USICTL0 &= ~USIOE;       // SDA = input

              SLV_Addr = 0x90;         // Reset slave address

              I2C_State = 0;           // Reset state machine

              break;

 

      case 8: // Receive data byte

              USICTL0 &= ~USIOE;       // SDA = input

              USICNT |=  0x08;         // Bit counter = 8, RX data

              I2C_State = 10;          // Go to next state: Test data and (N)Ack

            

                          break;

 

 

              USICTL0 |= USIOE;        // SDA = output

            READ_ADDR1 = USISRL;

 

            //I2C_Send_Data();

              if (USISRL == MST_Data)  // If data valid...

              {

                USISRL = 0x00;         // Send Ack

                                       //MST_Data++;            // Increment Master data

                P1OUT &= ~0x01;        // LED off

              }

              else

              {

                USISRL = 0xFF;         // Send NAck

                P1OUT |= 0x01;         // LED on: error

              }

              USICNT |= 0x01;          // Bit counter = 1, send (N)Ack bit

              I2C_State = 6;           // Go to next state: prep for next Start

              break;

            

 

    }

    

    Send_I2C = 1;

    

  USICTL1 &= ~USIIFG;                  // Clear pending flags

}

 

USI Slave Code:

 

Attached File  msp430g2x21_usi_08.c   11.02KB   0 downloads
 

Master Code:

 

 

Attached File  msp430g2x21_Injector.c   6.95KB   0 downloads
 

 

 

They both use the TI provided master .c and header

 

 

Attached File  MSP430_SWI2C_Master.c   5.94KB   0 downloads
Attached File  MSP430_SWI2C_Master.h   1.98KB   0 downloads

 

 

mspgcc compiler directives for the Master are:

 

sudo msp430-gcc -0s -g -Wall -mmcu=msp430g2231 msp430g2x21_Injector.c MSP430_SWI2C_Master.c -o MT.elf

 

For the Slave:

 

sudo msp430-gcc -0s -g -Wall -mmcu=msp430g2231 msp430g2x21_usi_08.c MSP430_SWI2C_Master.c -o MT.elf

 

And I am using mspdebug to program my launchpads. 


Viewing all articles
Browse latest Browse all 2077

Trending Articles