This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I am working with code examples from Resource Explorer - MSP430V3.60.00.10
Two files describe how to transmit a char array from the I2C slave to the I2C master.
The file names are.
MSP430F55xx_uscib0_i2c_10.c Slave transmits to the master
MSP430F55xx_uscib0_i2c_11.c master receives transmission from the slave.
I am using code composure 6.0 to debug this code. I have 2 devices connected through P3.0 and P3.1 Both pins have 10K resistors on it.
I actually got the master to transmit to the slave....That was a nightmare but my code works....Now I need to get the slave to transmit to the master.
The code examples are quite bad, as I determined from the experience using example code to create master to slave traansmission....but I cannot get this new code to work.
The issue is that both the slave and the master get stuck on the interrupt....nothing is happening.
Here is the 2 codes:....again straight from the example. Why do they both the slave and the master get hung on the interrupt?
(Note I removed the copywrite header from this post to reduce the need to read all of it but it is TI code protected by their copywrite.)
SLAVE CODE - Transmitting to a master
//****************************************************************************** // // Slave code // - slave transmits to master // // This is copied from MSP430F55xx_uscib0_i2c_11.c //****************************************************************************** #include <msp430.h> unsigned char *PTxData; // Pointer to TX data const unsigned char TxData[] = // Table of data to transmit { 0x11, 0x22, 0x33, 0x44, 0x55 }; int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P3SEL |= 0x03; // Assign I2C pins to USCI_B0 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 UCB0IE |= UCTXIE + UCSTPIE + UCSTTIE; // Enable STT and STP interrupt // Enable TX interrupt while (1) { PTxData = (unsigned char *)TxData; // Start of TX buffer __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until master // finishes RX __no_operation(); // Set breakpoint >>here<< and } // read out the TXByteCtr counter } //------------------------------------------------------------------------------ // The USCI_B0 data ISR TX vector is used to move data from MSP430 memory to the // I2C master. PTxData points to the next byte to be transmitted, and TXByteCtr // keeps track of the number of bytes transmitted. //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // The USCI_B0 state ISR TX vector is used to wake up the CPU from LPM0 in order // to do processing in the main program after data has been transmitted. LPM0 is // only exit in case of a (re-)start or stop condition when actual data // was transmitted. //------------------------------------------------------------------------------ #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: // Vector 6: STTIFG UCB0IFG &= ~UCSTTIFG; // Clear start condition int flag break; case 8: // Vector 8: STPIFG UCB0IFG &= ~UCSTPIFG; // Clear stop condition int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 if data was transmitted break; case 10: break; // Vector 10: RXIFG case 12: // Vector 12: TXIFG UCB0TXBUF = *PTxData++; // Transmit data at address PTxData break; default: break; } }
MASTER CODE
//****************************************************************************** // // Master code // - Master receives data from slave // // // This is copied from MSP430F55xx_uscib0_i2c_10.c // //****************************************************************************** #include <msp430.h> unsigned char *PRxData; // Pointer to RX data unsigned char RXByteCtr; volatile unsigned char RxBuffer[128]; // Allocate 128 byte of RAM int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P3SEL |= 0x03; // 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 = 0x48; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0IE |= UCRXIE; // Enable RX interrupt while (1) { PRxData = (unsigned char *)RxBuffer; // Start of RX buffer RXByteCtr = 5; // Load RX byte counter while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until all data // is RX'd __no_operation(); // Set breakpoint >>here<< and } // read out the RxBuffer buffer } //------------------------------------------------------------------------------- // The USCI_B0 data ISR is used to move received data from the I2C slave // to the MSP430 memory. It is structured such that it can be used to receive // any 2+ number of bytes by pre-loading RXByteCtr with the byte count. //------------------------------------------------------------------------------- #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: // Vector 10: RXIFG RXByteCtr--; // Decrement RX byte counter if (RXByteCtr) { *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData if (RXByteCtr == 1) // Only one byte left? UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition } else { *PRxData = UCB0RXBUF; // Move final RX data to PRxData __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU } break; case 12: break; // Vector 12: TXIFG default: break; } }
I never did get this code to work.
The code was written by someone who did not read the programming manual and certainly did not test the code. The I2C code examples don't work. I am working with the MSP430F5529, MSP430G2553. The code is omitting a lot of setting required for proper operation. I ended up having to design and code the i2c from scratch. I am now doing the same thing with the MSP430G2553. Needless to say I am wasting time I did not budget for. It is costing me.
Thanks Texas Instruments !
I2C examples need to be reviewed and rewritten.
**Attention** This is a public forum