Tool/software:
Hi all,
I've been scratching my head on this one. Long story short, I am teaching myself I2C on the MSP430FR5969. I made the following circuit, consisting of an Arduino UNO and a MSP430FR5969 Launchpad. I connected P1.6 (SDA) and P1.7 (SCL) on the launchpad to SDA and SCL pins on the Arduino UNO. I also set the Launchpad to be a master transmitter and the Arduino Uno to be a slave receiver. I also have two 4.7 kOhm resistors connecting the SDA and SCL to a 5 V rail.
What I have noticed is that the Launchpad would communicate through I2C initially because I can see the characters being received by the Arduino Uno via the serial monitor. But in the second time, the Launchpad will not run the ISR. I added some breakpoints and noticed that UCSCLLOW would not change. It remains 0. But when I reset the Arduino UNO and run the Launchpad with breakpoints again, UCSCLLOW would change to 1 right after I set UCTXSTT to the UCB0CTLW0 register.
I'm really confused. Some help would be greatly appreciated. I attached the two codes below. The address of the Arduino UNO is set to be 4.
#include <msp430.h>
#include <stdbool.h>
#include <stdint.h>
static inline
void launchpad_clk_config(void) {
// The SMCLK will be used for both the SPI communication and the timers.
// Due to the FRAM, we need to add in a wait condition so that higher frequencies can be used.
CSCTL0_H = CSKEY >> 8; // Unlock CS registers for modification.
CSCTL1 = ~DCORSEL & ~DCOFSEL_2; // Set DCO to 1 MHz
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; //
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers
CSCTL0_H = 0; // Lock CS registers back.
}
#define LP_SDA BIT6
#define LP_SCL BIT7
static inline
void launchpad_env_config(void) {
P1SEL1 |= LP_SDA;
P1SEL0 &= ~LP_SDA;
P1SEL1 |= LP_SCL;
P1SEL0 &= ~LP_SCL;
UCB0CTL1 |= UCSWRST;
UCB0CTLW0 |= UCMODE_3 + UCSYNC + UCMST + UCSSEL_2; // Using the SMCLK, and transmit.
UCB0BRW = 10; // SMCLK will generate a clock of 12 MHz, which will be divided by 30 to yield 400 KHz
UCB0CTLW1 = UCASTP_2; // automatic STOP assertion
UCB0CTL1 &= ~UCSWRST; // eUSCI_B in operational state
UCB0IFG = 0;
}
static inline
void launchpad_env_write(const char addr, const char bytes) {
UCB0CTL1 |= UCSWRST;
UCB0TBCNT = bytes;
UCB0I2CSA = addr;
UCB0CTL1 &= ~UCSWRST;
UCB0CTLW0 |= UCTR;
UCB0IE |= UCTXIE0 + UCSTTIE + UCNACKIE;
UCB0CTLW0 |= UCTXSTT;
}
char num = '9';
void main(void) {
WDTCTL = WDTPW | WDTHOLD;
PM5CTL0 &= ~LOCKLPM5;
launchpad_clk_config();
launchpad_env_config();
__enable_interrupt();
launchpad_env_write(4, 1);
launchpad_env_write(4, 1);
}
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void) {
switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG)) {
case USCI_NONE:
__no_operation();
break;
case USCI_I2C_UCNACKIFG:
__no_operation();
break;
case USCI_I2C_UCTXIFG0:
UCB0TXBUF = num++;
break;
case USCI_I2C_UCRXIFG0:
__no_operation();
break;
default:
break;
}
return;
}
'
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop() {
delay(1);
}
void receiveEvent(int howMany) {
while (Wire.available()) {
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
}