Hi everyone,
I am trying to set up a MSP430G2553 as a slave to relay ADC information to a raspberry pi. Here's the relevant part of my code:
#include <msp430.h>
volatile int i = 0;
volatile int bytectr = 0;
volatile int output[3] = {0};
volatile int RXData = 0;
volatile int reg = 0;
volatile int VAR_INPUT[34];
void getadc();
void inttoarray();
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
//BCSCTL1 = CALBC1_1MHZ; // Set range
//DCOCTL = CALDCO_1MHZ; // SMCLK = DCO = 1MHz
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
//P1DIR |= BIT0;
//P1OUT &= ~BIT0;
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode
UCB0I2COA = 0x48; // Own Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0I2CIE |= UCSTPIE + UCSTTIE; // Enable STT and STP interrupt
IE2 |= UCB0TXIE; // Enable RX interrupt
//__enable_interrupt();
while (1)
{
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}
}
void inttoarray()
{
VAR_INPUT[0] = reg;
if(reg == 0)
VAR_INPUT[0] = 8;
VAR_INPUT[1] = RXData / 256;
RXData -= VAR_INPUT[1] * 256;
VAR_INPUT[2] = RXData;
}
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
//VAR_INPUT[0] = 0x11;
//VAR_INPUT[1] = 0x22;
//VAR_INPUT[2] = 0x33;
//VAR_INPUT[3] = 0x44;
while((IFG2 & UCB0TXIFG) == 0);
UCB0TXBUF = VAR_INPUT[i];
i++;
}
#pragma vector = USCIAB0RX_VECTOR// Received start bit
__interrupt void USCIAB0RX_ISR(void)
{
//UCB0TXBUF = 0x44;
//__delay_cycles(1000);
if(UCB0CTL1 & UCTR) //data requested
{
// if(UCB0STAT & UCSTTIFG)
// {
//getadc(); //<- ideally I would like this here
// }
i = 0;
bytectr = 0;
UCB0STAT &= ~(UCSTPIFG + UCSTTIFG); // Clear interrupt flags
if (bytectr != 0) // Check TX byte counter
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0 if data was
}
else
{
reg = UCB0RXBUF;
UCB0STAT &= ~UCSTPIFG; // Clear start condition int flag
if(reg == 8)
reg = 0; //use 0 internally
bytectr = 3;
getadc();
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
// TXData++; // Increment data
}
}
void getadc()
{
ADC10CTL0 &= ~ENC; // Disable ADC
ADC10CTL1 = (reg *0x1000u) + ADC10DIV_3; // Temp Sensor ADC10CLK/4
ADC10CTL0 = ADC10ON | ADC10SHT_0 | SREF_0; // reference generator ON/ADC10 ON
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
while ( ADC10CTL1 & ADC10BUSY ); // Wait for ADC to complete
RXData = ADC10MEM;
inttoarray();
}
Here is what the master sends:
START (transmit)
REGISTER_BYTE
STOP
START (receive)
(I would ideally like to call getadc() here)
RECIEVED_BYTE_1
RECIEVED_BYTE_2
RECIEVED_BYTE_3
STOP
The code works fine with a MSP430 as the master(unless my master has issues as well) but not with the Pi. The Pi appears to send the register byte correctly but it seems to cut off the first bit of the first byte of RECIEVED_BYTE_1 with the rest of the transmission being lost. I noticed that when I comment out getadc(), the pi will receive any bytes I send it. I'm new to i2c and find this very confusing. Any help would be really appreciated.