Hi 2E2,
I am using the MSP430FR2433 and I want to communicate with the PN532 board via I2C. My goal is to send the following array (version_buff[9] = {0X00,0X00,0XFF,0X01,0XFF,0XD4,0X02,0XD5,0X00,}) to the PN532 and then save its response in a variable. I am using an example code but when I send UCB0TXBUF = TransmitRegAddr (I don't know why) it should read something and enter again in the interrupt. The second time I do not enter the interrupt and I get stuck in the line __bis_SR_register(LPM0_bits + GIE).
If someone can help me to solve the error or another way to send the array I mentioned before and then read a response.
Thank you.
#include "nfc.h" #include "msp430.h" typedef enum I2C_ModeEnum{ IDLE_MODE, NACK_MODE, TX_REG_ADDRESS_MODE, RX_REG_ADDRESS_MODE, TX_DATA_MODE, RX_DATA_MODE, SWITCH_TO_RX_MODE, SWITHC_TO_TX_MODE, TIMEOUT_MODE } I2C_Mode; /*constantes de NFC*/ unsigned char TransmitBuffer[9] = {0}; unsigned char TXByteCtr = 0; unsigned char ReceiveIndex = 0; unsigned char ReceiveBuffer[50]; unsigned char RXByteCtr = 0; unsigned char TransmitIndex = 0; unsigned char imagen[150]; I2C_Mode MasterMode = IDLE_MODE; unsigned char TransmitRegAddr = 0; unsigned char nfc_buf[NFC_CMD_BUF_LEN]; static const unsigned char version_buff[9] = {0X00,0X00,0XFF,0X01,0XFF,0XD4,0X02,0XD5,0X00,}; unsigned char checksum; I2C_Mode I2C_Master_WriteReg(unsigned char dev_addr, unsigned char reg_addr, const unsigned char *reg_data, unsigned char count); I2C_Mode I2C_Master_ReadReg(unsigned char dev_addr, unsigned char reg_addr, unsigned char count); void CopyArray(const unsigned char *source, unsigned char *dest, unsigned char count); void Configuracion_I2C(void); unsigned int get_version(void); int main() { WDTCTL = WDTPW | WDTHOLD; Configuracion_I2C(); PM5CTL0 &= ~LOCKLPM5; __enable_interrupt(); while(1) { get_version(); unsigned int versiondata = get_version(); //guardar version en versiondata if (! versiondata) { //Si devuelve 0 es que no ha detectado while (1); } while(1); } } void Configuracion_I2C(void) { UCB0CTLW0 = UCSWRST; // Enable SW reset UCB0CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK UCB0BRW = 160; // fSCL = SMCLK/160 = ~100kHz UCB0I2CSA = PN532_I2C_ADDRESS; // Slave Address UCB0CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation UCB0IE |= UCNACKIE; P1SEL1 &= ~BIT3; P1SEL0 |= BIT3; P1SEL1 &= ~BIT2; P1SEL0 |= BIT2; } I2C_Mode I2C_Master_ReadReg(unsigned char dev_addr, unsigned char reg_addr, unsigned char count) { /* Initialize state machine */ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; RXByteCtr = count; TXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB0IE &= ~UCRXIE; // Disable RX interrupt UCB0IE |= UCTXIE; // Enable TX interrupt UCB0CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts*/ return MasterMode; } I2C_Mode I2C_Master_WriteReg(unsigned char dev_addr, unsigned char reg_addr, const unsigned char *reg_data, unsigned char count) { /* Initialize state machine */ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; //Copy register data to TransmitBuffer CopyArray(reg_data, TransmitBuffer, count); TXByteCtr = count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB0I2CSA = dev_addr; UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB0IE &= ~UCRXIE; // Disable RX interrupt UCB0IE |= UCTXIE; // Enable TX interrupt UCB0CTLW0 |= UCTR; UCB0CTLW0 |= UCTXSTT; // I2C TX, start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts return MasterMode; } void CopyArray(const unsigned char *source, unsigned char *dest, unsigned char count) { unsigned char copyIndex = 0; for (copyIndex = 0; copyIndex < count; copyIndex++) { *dest = *source; source++; dest++; } } #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 { //Must read from UCB0RXBUF unsigned char rx_val = 0; switch(__even_in_range(UCB0IV, 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 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 rx_val = UCB0RXBUF; if (RXByteCtr) { ReceiveBuffer[ReceiveIndex++] = rx_val; RXByteCtr--; } if (RXByteCtr == 1) { UCB0CTLW0 |= UCTXSTP; } else if (RXByteCtr == 0) { UCB0IE &= ~UCRXIE; MasterMode = IDLE_MODE; __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0 switch (MasterMode) { case TX_REG_ADDRESS_MODE: UCB0TXBUF = TransmitRegAddr; if (RXByteCtr) MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now else MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer break; case SWITCH_TO_RX_MODE: UCB0IE |= UCRXIE; // Enable RX interrupt UCB0IE &= ~UCTXIE; // Disable TX interrupt UCB0CTLW0 &= ~UCTR; // Switch to receiver MasterMode = RX_DATA_MODE; // State state is to receive data UCB0CTLW0 |= UCTXSTT; // Send repeated start if (RXByteCtr == 1) { //Must send stop since this is the N-1 byte while((UCB0CTLW0 & UCTXSTT)); UCB0CTLW0 |= UCTXSTP; // Send stop condition } break; case TX_DATA_MODE: if (TXByteCtr) { UCB0TXBUF = TransmitBuffer[TransmitIndex++]; TXByteCtr--; } else { //Done with transmission UCB0CTLW0 |= UCTXSTP; // Send stop condition MasterMode = IDLE_MODE; UCB0IE &= ~UCTXIE; // disable TX interrupt __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; default: __no_operation(); break; } break; default: break; } } unsigned int get_version(void) { unsigned int version; I2C_Master_WriteReg(PN532_I2C_ADDRESS , 0, version_buff, 8); I2C_Master_ReadReg(PN532_I2C_ADDRESS ,0, 12); CopyArray(ReceiveBuffer, nfc_buf, 12); version = nfc_buf[7]; version <<= 8; version |= nfc_buf[8]; version <<= 8; version |= nfc_buf[9]; version <<= 8; version |= nfc_buf[10]; return version; }