Other Parts Discussed in Thread: CC1310,
Hi,
Here i am using MSP430G2102 microcontroller as a slave device and CC1310 TI chip as a master device.
TI chip is wake based on gpio high/low. Here we have used LPM4 mode.
Device gets wake up on getting interrupt of any key press (P1.1, P1.2 P1.3,P1.4,P1.5).and device than transmit the data of key press to the master device.
Master device send the NACK on receiving the key press data and master than send the data 0xAA to the msp430 slave device. Once the MSP430 slave device receives the 0xAA it disables the gpio(Port Pin P1.0) which cuts the power of master TI CC1310 chip.
But here the problem i am facing in else part of switch case 10 is that though in debug mode msp430 device received the 0xAA but than also the pin P1.0 is sometimes getting high and remain permanent high instead of low by this statement (P1OUT &= ~BIT1).
here please find the i2c slave transmit receive code for your reference, and please inform me for the below query.
1) In switch case 10 else part though the msp430 device getting 0xAA but the line (P1OUT &= ~BIT1) do not make pin low permanently but sometimes it remain high permanently . can u please let me know why this happen? and what is the problem in my code.
2) is i am handling the low power mode 4 correctly in my attached code?
3) Provide me the solution so that everytime while getting 0xAA my gpio pin P1.0 get disable which is right now remain most of time high.
4) Is my I2c routine in code okay?
Code:
#include <msp430.h>
char flag=0;
char Slave_Tx = 1;
char SLV_Data = 0; // Variable for transmitted data
char SLV_Addr = 0x90; // Address is 0x48<<1 for R/W
int I2C_State = 0; // State variable
int i=0;
void i2c_init(void)
{
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
__enable_interrupt();
}
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;
P1DIR |= (BIT7 + BIT6 + BIT0); // Set P1.0 to output direction
P1DIR &= ~(BIT1 + BIT2 + BIT3 + BIT4 + BIT5);
P1OUT |= (BIT7 + BIT6);
P1OUT &= ~BIT0;
P1IES |= (BIT1 + BIT2 + BIT3 + BIT4 + BIT5); // P1.1 Hi/lo edge
P1IFG &= ~(BIT1 + BIT2 + BIT3 + BIT4 + BIT5); // IFG cleared
P1IE |= (BIT1 + BIT2 + BIT3 + BIT4 + BIT5); // interrupt enabled
i2c_init();
while(1)
{
if(flag==1)
{
P1OUT |= BIT0;
}
else
{
P1DIR |= BIT0;
P1OUT &= ~BIT0;
__bis_SR_register(LPM4_bits + GIE);
}
}
}
//******************************************************
// USI interrupt service routine
//******************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USI_VECTOR))) USI_TXRX (void)
#else
#error Compiler not supported!
#endif
{
if (USICTL1 & USISTTIFG) // Start entry?
{
I2C_State = 2; // Enter 1st state on start
}
switch (I2C_State)
{
case 0: //Idle, should not get here
break;
case 2: //RX Addres
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
I2C_State = 8; // Go to next state: TX data
}
else
{
USISRL = 0xFF; // Send NAck
I2C_State = 6; // Go to next state: prep for next Start
flag=0;
}
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
if (Slave_Tx)
{
USICTL0 |= USIOE; // SDA = output
USISRL = SLV_Data; // Send data byte
}
else
{
USICTL0 &= ~USIOE; // SDA = input
}
USICNT |= 0x08; // Bit counter = 8, RX data
I2C_State = 10; // Go to next state: Test data and (N)Ack
break;
case 10: // Receive Data (N)Ack
if (Slave_Tx)
{
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack
I2C_State = 12; // Go to next state: check (N)Ack
}
else
{
// Check Data & TX (N)Ack
USICTL0 |= USIOE; // SDA = output
if (USISRL == 0xAA) // If data valid...
{
USISRL = 0x00; // Send Ack
Slave_Tx = 1;
flag=0;
}
else
{
USISRL = 0xFF; // Send NAck
}
USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
I2C_State = 6; // Go to next state: prep for next Start
}
break;
case 12: // Process Data Ack/NAck
if (USISRL & 0x01) // If Nack received...
{
Slave_Tx = 0;
}
// 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
}
// Port 1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
if (P1IFG & BIT1)
{
SLV_Data = 1;
P1IFG &= ~BIT1; // P1.1 IFG cleared
}
if (P1IFG & BIT2)
{
SLV_Data = 2;
P1IFG &= ~BIT2; // P1.2 IFG cleared
}
if (P1IFG & BIT3)
{
SLV_Data = 3;
P1IFG &= ~BIT3; // Reset Port1 interrupt flag
}
if (P1IFG & BIT4)
{
SLV_Data = 4; // Save the state of the switch 4
P1IFG &= ~BIT4; // P1.4 IFG cleared
}
if (P1IFG & BIT5)
{
SLV_Data = 5; // Save the state of the switch 5
P1IFG &= ~BIT5; // P1.5 IFG cleared
}
flag=1;
__bic_SR_register_on_exit(LPM4_bits);
}
Waiting fo your reply.
Thanks