Tool/software: Code Composer Studio
MSP430FR2355
Code Composer Studio
Version: 8.3.1.00004
Slave: MPU6050 ( Accel / Gyro) module
I can Init the MPU6050 no problem.
But when I get to the data gathering ( TX and RX portion), it expected to see the
Master: I2C as TX
TX ADDRESS + Code + RESTART or STOP ( 0x68 + 0x3B + S)
Master:I2C as RX
TX ADDRESS, expect a 1 Byte Response then NACK. (0x68 || data Byte || NACK) Then master expect to acknowledge with a NACK to end transmission
this is suppose to repeat;
What I get is
TX ADDRESS + Stop ( 0x68 + S)
RX ADDRESS || 0x00 + 0x00 || NACK
example below from logic analyser
Really do not know why this is occurring why the master MSP430FR2355 is Transmitting the address only but not the data?
tried putting delays at various location, tried different clock speeds currently set to /8 ( tried from /2 to /20 no luck)
this is the Scope trace Yellow is the data line the Blue is P3 BIT4 ( I place a P3 Bit4 to go Hi and Low within the Interrupt routine, it captures this glitch At the address portion of the I2C Protocol
From the Master
#include <msp430fr2355.h>
#include "stdint.h"
/**
* MPU-6050 I2C = 0x68
*
*
*/
void I2C_busy(void);
void delay(void);
const unsigned int MPU_address = 0x68; // MPU-6050 i2c Address
const unsigned int Accel_Xout_H = 0x003B;
const unsigned int Accel_Xout_L = 0x003C;
const unsigned int Accel_Yout_H = 0x003D;
const unsigned int Accel_Yout_L = 0x003E;
const unsigned int Accel_Zout_H = 0x003F;
const unsigned int Accel_Zout_L = 0x0040;
const unsigned int Gyro_Xout_H = 0x0043;
const unsigned int Gyro_Xout_L = 0x0044;
const unsigned int Gyro_Yout_H = 0x0045;
const unsigned int Gyro_Yout_L = 0x0046;
const unsigned int Gyro_Zout_H = 0x0047;
const unsigned int Gyro_Zout_L = 0x0048;
unsigned int RXData = 0;
unsigned int TXByteCtr = 0;
unsigned int SlaveFlag = 0;
unsigned int RXcnt = 0;
volatile unsigned int tx_cntr = 0;
volatile unsigned int stop = 0;
volatile unsigned int read = 0;
signed int TXData[] = {0x6B, 0x00, 0x1A, 0x04, 0x1B, 0x00, 0x1C, 0x00};
unsigned int RX[4];
unsigned int RX1[0x0100];
unsigned int RX1cnt = 0;
signed int x_acc = 0;
signed int y_acc = 0;
signed int z_acc = 0;
signed int x_gyr = 0;
signed int y_gyr = 0;
signed int z_gyr = 0;
unsigned int valid = 0;
signed int acc_led = 0;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1SEL0 |= BIT2 | BIT3; // I2C pins
P5DIR |= BIT0 | BIT1 | BIT2 | BIT3 | BIT4; // Stepper driver 0=DIR, 1=STEP, 3-4-5 step value
P5OUT = 0x00;
P3DIR = 0xFF;
P3OUT = 0x00;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Configure USCI_B0 for I2C mode
UCB0CTLW0 |= UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync
UCB0CTLW1 |= UCASTP_0; // NO Automatic stop generated
// after UCB0TBCNT is reached
UCB0BRW = 0x0008; // baudrate = SMCLK / 8 ------------> 32
UCB0TBCNT = 0x0000; // byte cntr disabled
UCB0I2CSA = MPU_address; // Slave address of MPU-6050
UCB0CTL1 &= ~UCSWRST;
UCB0IE |= UCRXIE | UCTXIE0 | UCNACKIE | UCTXSTP; // EN INT TX, RX, NACK
__bis_SR_register(GIE); // enable interrupt
while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
I2C_busy();
tx_cntr = 0x00;
TXByteCtr = 0x02;
UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x6B 0x00
I2C_busy();
TXByteCtr = 0x02;
UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x1A 0x00
I2C_busy();
TXByteCtr = 0x02;
UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x1B 0x00
I2C_busy();
TXByteCtr = 0x02;
UCB0CTLW0 |= UCTR | UCTXSTT; // TX 0x1C 0x00
I2C_busy();
/*
* MPU6050 init completed
*/
tx_cntr = 0x0000;
TXData[0] = 0x3B;
TXData[1] = 0x3C;
TXData[2] = 0x3D;
TXData[3] = 0x3E;
TXData[4] = 0x3F;
TXData[5] = 0x40;
TXData[6] = 0x00;
TXData[7] = 0x00;
RXcnt = 0x00;
// RX data
// Master |S|AD+W| |RA| |S|AD+R| | |ack|
// Slave |ack| |ack| | |ack|Data| |
while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
I2C_busy();
while(1)
{
P3OUT = 0x00;
tx_cntr = 0x00;
TXByteCtr = 0x01;
// UCB0CTLW0 |= UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCTR; // inTX mode
UCB0CTLW1 |= UCASTP0;
// UCB0TBCNT = 0x03; // tx 2 bytes
// UCB0CTLW0 &= ~UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCTXSTT; // I2C start condition
I2C_busy();
P3OUT |= BIT0;
// UCB0CTLW0 |= UCSWRST; // Software reset enabled
UCB0CTLW0 &= ~UCTR ; // Receive Mode
UCB0CTLW1 |= UCASTP1;
UCB0TBCNT = 0x01; // rx 1 bytes
// UCB0CTLW0 &= ~UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCTXSTT; // I2C start condition inTX mode
I2C_busy();
while(read) __no_operation();
P3OUT |= BIT1;
if(valid)
{
RX1[RX1cnt++] = x_acc;
if(RX1cnt > 0x00FF) RX1cnt = 0x0000;
acc_led = x_acc >>8;
// P3OUT = acc_led; // like to see the results in real time
if(acc_led > 128)
{
P5OUT |= BIT0;
P5OUT |= BIT1;
delay(); // stepper motor delay pulse just too fast
P5OUT &= BIT1;
delay(); // stepper motor delay pulse just too fast
}
else if (z_gyr < -128)
{
P5OUT &= ~BIT0;
P5OUT |= BIT1;
delay(); // stepper motor delay pulse just too fast
P5OUT &= BIT1;
delay(); // stepper motor delay pulse just too fast
}
P3OUT |= BIT2;
}
}
}
void I2C_busy(void)
{
unsigned int wait;
while (UCB0STATW & UCBBUSY)
{
for(wait = 0xFFFF; wait == 0; wait--)__no_operation();
}
}
void delay(void)
{
unsigned int stepper_pulse_delay;
for(stepper_pulse_delay = 0xFFFF; stepper_pulse_delay == 0; stepper_pulse_delay--) __no_operation();
}
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
{
volatile unsigned int I2C_int;
I2C_int = UCB0IV;
if(I2C_int == UCIV__UCTXIFG0) // TX buffer is empty
{
if (TXByteCtr) // Check TX byte counter
{
P3OUT |= BIT4;
TXByteCtr--;
UCB0TXBUF = TXData[tx_cntr]; // Load TX buffer
tx_cntr++;
stop = 0x01; // Decrement TX byte counter
P3OUT &= ~BIT4;
}
else
{
stop = 0x00;
UCB0CTLW0 |= UCTXSTP; // I2C stop condition
}
}
else if(I2C_int == UCIV__UCRXIFG0) // RX data present
{
UCB0CTLW0 |= UCTXSTP;
RXData = UCB0RXBUF;
RX[RXcnt] = RXData;
RXcnt++;
if(RXcnt > 0x0001)
{
RXcnt = 0;
x_acc = RX[1] | (RX[0]<<8);
valid = 0x0001;
}
valid = 0x0001;
read = 0x0000;
P3OUT |= BIT5;
}
else if(I2C_int == UCIV__UCNACKIFG) // NACK received
{
stop = 0x00;
read = 0x0000;
UCB0CTLW0 |= UCTXSTP; // I2C stop condition
}
else if(I2C_int == UCIV__UCSTPIFG ) // Stop received
{
stop = 0x00;
}
}

