Other Parts Discussed in Thread: MSP430WARE, MSP430G2553, MSP430G2432
Hi all,
I am making my first steps into using IC2 on the MSP430 value line devices, using code examples supplied in the latest MSP430Ware. The examples are as follows:
MSP430G2553 has msp430g2xx3_uscib_i2c_04 - This is the Master using the USCI and should receive a single byte from the MSP430 slave.
MSP430G2432 has msp430g2xx2_usi_09 - This is the Slave using the USI and should transmit a single byte to the MSP430 master.
I have the devices connected via a breadboard, with Vcc from one board connected via 10k resistors to the SDA and SCL lines (P1.6 SDA and P1.7 SCL) as per the code example. I have given them a common ground as well, as attempting to run them off 2 computers.
So at the moment not a lot appears to happen, when I run the master, the slave reacts and jumps into the interrupt and the red LED is illuminated. But the code then jumps to the end not executing the state machine code. I suspect this is due to the process timing out as I step through the code, however if I just run both devices and press reset on the master the red LED is again illuminated (staying on) on the slave as when I stepped through the code.
I don't have access to an oscilloscope at the moment, but not 100% aufait with IC2.
So really after some advice and if I am going the wrong way about this, any suggestions appreciated.
Thanks in advance,
Ant
/* --COPYRIGHT--,BSD_EX
* Copyright (c) 2012, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* MSP430 CODE EXAMPLE DISCLAIMER
*
* MSP430 code examples are self-contained low-level programs that typically
* demonstrate a single peripheral function or device feature in a highly
* concise manner. For this the code may rely on the device's power-on default
* register values and settings such as the clock configuration and care must
* be taken when combining code from several examples to avoid potential side
* effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
* for an API functional library-approach to peripheral configuration.
*
* --/COPYRIGHT--*/
//******************************************************************************
// MSP430G2xx3 Demo - USCI_B0 I2C Master RX single bytes from MSP430 Slave
//
// Description: This demo connects two MSP430's via the I2C bus. The master
// reads from the slave. This is the master code. The data from the slave
// transmitter begins at 0 and increments with each transfer. The received
// data is in R5 and is checked for validity. If the received data is
// incorrect, the CPU is trapped and the P1.0 LED will stay on. The USCI_B0
// RX interrupt is used to know when new data has been received.
// ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.2MHz
//
// *** to be used with "msp430g2xx3_uscib0_i2c_05.c" ***
//
// /|\ /|\
// MSP430G2xx3 10k 10k MSP430G2xx3
// slave | | master
// ----------------- | | -----------------
// -|XIN P1.7/UCB0SDA|<-|---+->|P1.7/UCB0SDA XIN|-
// | | | | | 32kHz
// -|XOUT | | | XOUT|-
// | P1.6/UCB0SCL|<-+----->|P1.6/UCB0SCL |
// | | | P1.0|--> LED
//
// D. Dang
// Texas Instruments Inc.
// February 2011
// Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include <msp430.h>
unsigned char RXData;
unsigned char RXCompare;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1OUT &= ~BIT0; // P1.0 = 0
P1DIR |= BIT0; // P1.0 output
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x048; // Slave Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0RXIE; // Enable RX interrupt
RXCompare = 0; // Used to check incoming data
while (1)
{
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT; // I2C start condition
while (UCB0CTL1 & UCTXSTT); // Start condition sent?
UCB0CTL1 |= UCTXSTP; // I2C stop condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
if (RXData != RXCompare) // Trap CPU if wrong
{
P1OUT |= BIT0; // P1.0 = 1
while (1); // Trap CPU
}
RXCompare++; // Increment correct RX value
}
}
// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
RXData = UCB0RXBUF; // Get RX data
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
/* --COPYRIGHT--,BSD_EX
* Copyright (c) 2012, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* MSP430 CODE EXAMPLE DISCLAIMER
*
* MSP430 code examples are self-contained low-level programs that typically
* demonstrate a single peripheral function or device feature in a highly
* concise manner. For this the code may rely on the device's power-on default
* register values and settings such as the clock configuration and care must
* be taken when combining code from several examples to avoid potential side
* effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
* for an API functional library-approach to peripheral configuration.
*
* --/COPYRIGHT--*/
//******************************************************************************
// MSP430G2xx2 Demo - I2C Slave Transmitter, single byte
//
// Description: I2C Slave communicates with I2C Master using
// the USI. Slave data is sent and increments from 0x00 with each transmitted
// byte which is verified by the Master.
// LED off for address or data Ack; LED on for address or data NAck.
// ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz
//
// ***THIS IS THE SLAVE CODE***
//
// Slave Master
// (MSP430G2xx2_usi_06.c)
// MSP430G2xx2 MSP430G2xx2
// ----------------- -----------------
// /|\| XIN|- /|\| XIN|-
// | | | | | |
// --|RST XOUT|- --|RST XOUT|-
// | | | |
// LED <-|P1.0 | | |
// | | | P1.0|-> LED
// | SDA/P1.7|------->|P1.7/SDA |
// | SCL/P1.6|<-------|P1.6/SCL |
//
// Note: internal pull-ups are used in this example for SDA & SCL
//
// D. Dang
// Texas Instruments Inc.
// December 2010
// Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include <msp430.h>
char SLV_Data = 248; // Variable for transmitted data
char SLV_Addr = 0x90; // Address is 0x48<<1 for R/W
int I2C_State = 0; // State variable
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog
if (CALBC1_1MHZ==0xFF) // If calibration constants erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;
P1OUT = 0xC0; // P1.6 & P1.7 Pullups
P1REN |= 0xC0; // P1.6 & P1.7 Pullups
P1DIR = 0xFF; // Unused pins as outputs
P2OUT = 0;
P2DIR = 0xFF;
USICTL0 = USIPE6+USIPE7+USISWRST; // Port & USI mode setup
USICTL1 = USII2C+USIIE+USISTTIE; // Enable I2C mode & USI interrupts
USICKCTL = USICKPL; // Setup clock polarity
USICNT |= USIIFGCC; // Disable automatic clear control
USICTL0 &= ~USISWRST; // Enable USI
USICTL1 &= ~USIIFG; // Clear pending flag
_EINT();
while(1)
{
LPM0; // CPU off, await USI interrupt
_NOP(); // Used for IAR
}
}
//******************************************************
// USI interrupt service routine
//******************************************************
#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
}
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
break;
case 4: // Process Address and send (N)Ack
if (USISRL & 0x01) // If read...
SLV_Addr++; // Save R/W bit
USICTL0 |= USIOE; // SDA = output
if (USISRL == SLV_Addr) // Address match?
{
USISRL = 0x00; // Send Ack
P1OUT &= ~0x01; // LED off
I2C_State = 8; // Go to next state: TX data
}
else
{
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
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: // Send Data byte
USICTL0 |= USIOE; // SDA = output
USISRL = SLV_Data; // Send data byte
USICNT |= 0x08; // Bit counter = 8, TX data
I2C_State = 10; // Go to next state: receive (N)Ack
break;
case 10:// Receive Data (N)Ack
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack
I2C_State = 12; // Go to next state: check (N)Ack
break;
case 12:// Process Data Ack/NAck
if (USISRL & 0x01) // If Nack received...
{
P1OUT |= 0x01; // LED on: error
}
else // Ack received
{
P1OUT &= ~0x01; // LED off
SLV_Data++; // Increment Slave data
}
// Prep for Start condition
USICTL0 &= ~USIOE; // SDA = input
SLV_Addr = 0x90; // Reset slave address
I2C_State = 0; // Reset state machine
break;
}
USICTL1 &= ~USIIFG; // Clear pending flags
}