I took the TI example for I2C "uscib0_i2c_08 and tried to convert it to use Port 4. It has a problem where it goes into the interrupt and sets the first bit but after that it hangs (goes back to the main loop and no more interrupts are sent). Here is the code:
#include <msp430.h>
unsigned char *PTxData; // Pointer to TX data
unsigned char TXByteCtr;
const unsigned char TxData[] = // Table of data to transmit
{
0x18, // reg = timer control
0x2 // data
};
int main(void)
{
unsigned int i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
PJDIR |= 0x02; // PJ.1 RTC switch
PJOUT = 0x0; // RTC switch low = RTC on
P4SEL = 0x06;
P4DIR |= 0x06;
PMAPPWD = 0x02D52; // Enable Write-access to modify port mapping registers
PMAPCTL |= PMAPRECFG;
P4MAP1 = PM_UCB1SDA;
P4MAP2 = PM_UCB1SCL;
PMAPPWD = 0; // Disable Write-Access to modify port mapping registers
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = 0xD2; // Slave Address is 0D2h = RTC
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE; // Enable TX interrupt
while (1)
{
for(i=0;i<10;i++); // Delay required between transaction
PTxData = (unsigned char *)TxData; // TX array start address
// Place breakpoint here to see each
// transmit operation.
TXByteCtr = sizeof TxData; // Load TX byte counter
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts
__no_operation(); // Remain in LPM0 until all data
// is TX'd
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
}
}
//------------------------------------------------------------------------------
// The USCIAB1TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB1IV,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: break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG
if (TXByteCtr) // Check TX byte counter
{
UCB1TXBUF = *PTxData++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB1CTL1 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
default: break;
}
}