Tool/software: Code Composer Studio
Hello Everyone,
I am implementing I2C communication. First, I am transmitting 5 bytes of data to my slave device. and after that I am receiving the response.
I already know the response, so I can compare the results. I am getting the expected response from the slave device.
My transmit function is working properly. i.e START--slaveAddress--Write--Ack--data1--Ack--data2--Ack--data3--Ack--data4--Ack--data5--Ack--STOP
But,
In my receive function, I am having problem that I can't stop this communication, I have written the stop I2C command, but it is not actually going to that command.
Let suppose I am expecting 3 bytes in response from the slave device. Then I am getting the following result.
START--SlaveAddress--READ--Acq--Data1--Acq--Data2--Acq--Data3--Acq--Unknown
I am checking the results in logic analyzer. I got to know from some other forum that I am not using LMP correctly.
I am attaching my code below, I shall be very thankful if someone can help.
Thank you
#include <msp430.h> char TXData[5] = { 0x5A, 0xCF, 0x00 }; //APDU initialization volatile unsigned char RXData[3]; // To save the received data unsigned char SlaveAddress = 0x48; // slave address volatile unsigned char TXByteCtr; volatile unsigned char TxByteCnt = 0; volatile unsigned char RxByteCnt = 0; unsigned char Rx; // To enable reception void Transmit(void); void Recieve(void); short crc_ret; //short final; unsigned short crc16_x25(char* pData, int length) { int i; unsigned short wCrc = 0xffff; while (length--) { wCrc ^= *(unsigned char *)pData++ << 0; for (i=0; i < 8; i++) wCrc = wCrc & 0x0001 ? (wCrc >> 1) ^ 0x8408 : wCrc >> 1; } return wCrc ^ 0xffff; } int main(void) { WDTCTL = WDTPW | WDTHOLD; //while(1); // Configure GPIO P8OUT |= BIT0; // Clear P8.0 output latch P8DIR |= BIT0; P7SEL0 |= BIT0 | BIT1; P7SEL1 &= ~(BIT0 | BIT1); // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5; // Configure USCI_B2 for I2C mode UCB2CTLW0 |= UCSWRST; // put eUSCI_B in reset state UCB2CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK; // I2C master mode, SMCLK UCB2BRW = 0x8; // baudrate = SMCLK / 8 UCB2CTLW0 &= ~UCSWRST; // clear reset register UCB2IE |= UCTXIE0 | UCNACKIE | UCRXIE0; // transmit, Receive and NACK interrupt enable crc_ret = crc16_x25(TXData, (sizeof(TXData) - 2)); // Calling CRC function TXData[3] = (char)crc_ret; TXData[4] = (char)((crc_ret&0xFF00)>>8); while(1) { __delay_cycles(2000); // Delay between transmissions UCB2I2CSA = SlaveAddress; // configure slave address TXByteCtr = 1; // Load TX byte counter Transmit(); //Implementing the transmit function __delay_cycles(2000); Rx = 1; Recieve(); //Implementing the receive function __delay_cycles(2000); } } #pragma vector = EUSCI_B2_VECTOR __interrupt void USCI_B2_ISR(void) { switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG)) { case USCI_NONE: break; // Vector 0: No interrupts case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG UCB2CTLW0 |= UCTXSTT; // resend start if NACK break; case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3 case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3 case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2 case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2 case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1 case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1 case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0 if (Rx < 3) // Check RX byte counter { RXData[RxByteCnt]= UCB2RXBUF; // Load TX buffer RxByteCnt++; Rx++; // Decrement TX byte counter __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } else { UCB2CTLW0 |= UCTXSTP; // I2C stop condition UCB2IFG &= ~UCRXIFG; // Clear USCI_B2 RX int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } break; case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0 if (TXByteCtr < (sizeof(TXData) + 1)) // Check TX byte counter { UCB2TXBUF = TXData[TxByteCnt]; // Load TX buffer TxByteCnt++; TXByteCtr++; // Decrement TX byte counter __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } else { TxByteCnt = 0; UCB2CTLW0 |= UCTXSTP; // I2C stop condition UCB2IFG &= ~UCTXIFG; // Clear USCI_B2 TX int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } break; case USCI_I2C_UCBCNTIFG: break; // Vector 26: BCNTIFG case USCI_I2C_UCCLTOIFG: break; // Vector 28: clock low timeout case USCI_I2C_UCBIT9IFG: break; // Vector 30: 9th bit default: break; } } void Transmit(void) { while (UCB2CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB2CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition __bis_SR_register(LMP0 + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data // is TX'd } void Recieve(void) { while (UCB2CTLW0 & UCTXSTP); // Ensure stop condition got se UCB2CTLW0 &= ~UCTR; UCB2CTLW0 |= UCTXSTT; __bis_SR_register(LMP0 +GIE); // Enter LPM0 w/ interrupts//start condition;