Good afternoon,
I've adapted the code from a TI application note, concretely tidc487 for my MSP430FR5969 to work with RF430CL330H boosterpack. Some pins had to be changed for i2C to work but it works.
The question is I'm able to see my INTO interrupt firing once. I configure this interrupt to fires upon the tag read. I get close to the tag with my phone, I recover my "hello world" message and my LED blinks. I remove my phone from the area next to the tag. The next time I approach my phone, I can recover the same "hello world" message. However, my ISR does not fire.
I attach the code next. I've tried to keep it short.
file main.c
void main (void) { volatile unsigned int test = 0; volatile unsigned int flags = 0; //unsigned char read_data[200]; MSP430_Init(); Low_Power_Delay_ms(20); while(!(Read_Register(STATUS_REG) & READY)){ //wait until READY bit has been set Low_Power_Delay_ms(1); } /****************************************************************************/ /* Errata Fix : Unresponsive RF - recommended firmware */ /****************************************************************************/ { // //Please implement this fix as given in this block. It is important that // //no line be removed or changed. unsigned int version; version = Read_Register(VERSION_REG); // read the version register. The fix changes based on what version of the // // RF430 is being used. Version C and D have the issue. Next versions are // // expected to have this issue corrected // // Ver C = 0x0101, Ver D = 0x0201 if (version == 0x0101 || version == 0x0201) { Write_Register(0xFFE0, 0x004E); Write_Register(0xFFFE, 0x0080); if (version == 0x0101) { // Ver C Write_Register(0x2a98, 0x0650); } else { // Ver D Write_Register(0x2a6e, 0x0650); } Write_Register(0x2814, 0); Write_Register(0xFFE0, 0); } //Upon exit of this block, the control register is set to 0x0 } // check to see if the memory contents are valid, if not put in a our default NDEF message. if(FRAM_Message[0] != 0xD2) { memcpy(FRAM_Message, RF430_DEFAULT_DATA , 48); } while (1) { Low_Power_Delay_ms(1); Update_RF430(); Low_Power_Delay_ms(20); while(!into_fired) {} into_fired = 0; // while(!(Read_Register(STATUS_REG) & READY)); //wait until READY bit has been set } } void Low_Power_Delay_ms(unsigned int ms){ TA1CTL |= TACLR; TA1CCR0 = ms*10; // leave time for the RF430CL33H to get itself initialized, 200=20ms TA1CTL |= MC__UP; // ACLK, up mode __bis_SR_register(LPM3_bits + GIE); TA1CTL |= MC__STOP; } void MSP430_Init(){ WDTCTL = WDTPW + WDTHOLD; // Turn off Watch Dog PMMCTL0 = PMMPW; // Open PMM Module PM5CTL0 &= ~LOCKLPM5; // Clear locked IO Pins CSCTL0_H = 0xA5; CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting = 8MHz CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = VLOCLK = 10kHz CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set VLOCLK / 1 //**** Drive unused pins low, for lowest power ***// P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF; P4DIR = 0xFF; P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00; P4OUT = 0x00; //*************************************************// Rf430_I2C_Init(); // Configure pins for I2C PORT_I2C_SEL0 &= ~(SCL + SDA); PORT_I2C_SEL1 |= SCL + SDA; Rf430_I2C_Init(); // DRIVE CS Low to indicate I2C Mode PORT_CS_SEL0 |= PORT_CS_PIN; PORT_CS_DIR |= PORT_CS_PIN; PORT_CS &= ~PORT_CS_PIN; //RST RF430 (in case board is still powered but the MSP430 reset for some reason - MSP430 RST button pushed for example) PORT_RST_SEL0 &= ~RST; PORT_RST_SEL1 &= ~RST; PORT_RST_OUT &= ~RST; //RF430CL330H device in reset PORT_RST_DIR |= RST; __delay_cycles(100); PORT_RST_OUT |= RST; //release the RF430CL330H //configure LEDs PORT_LED_SEL0 &= ~(LED5 + LED6); //GPIO PORT_LED_SEL1 &= ~(LED5 + LED6); //GPIO PORT_LED_DIR |= LED5 + LED6; //output PORT_LED_OUT &= ~(LED5 + LED6); //start out off // DRIVE CS Low to indicate I2C Mode PORT_CS_SEL0 |= PORT_CS_PIN; PORT_CS_DIR |= PORT_CS_PIN; PORT_CS &= ~PORT_CS_PIN; //configure pin for INTO interrupts PORT_INTO_SEL0 &= ~INTO; //GPIO PORT_INTO_SEL1 &= ~INTO; //GPIO PORT_INTO_DIR &= ~INTO; //input PORT_INTO_OUT |= INTO; //output high for pullup PORT_INTO_REN |= INTO; //internal pullup resistor PORT_INTO_IFG &= ~INTO; //clear interrupt flag PORT_INTO_IES |= INTO; //fire interrupt on high-to-low transition since INTO is setup active low //~ INT0 pin P1IE |= BIT4; Timer_Init(); } // ISR #pragma vector=PORT1_VECTOR __interrupt void PORT1_ISR(void) { //INTO interrupt fired if(PORT_INTO_IFG & INTO) { into_fired = 1; //PORT_INTO_IE &= ~INTO; //disable INTO PORT_INTO_IFG &= ~INTO; //clear interrupt flag PORT_LED_OUT ^= BIT6; __bic_SR_register_on_exit(LPM3_bits); //wake up to handle INTO } } /*****************Timer Functions*********************/ void Timer_Init(){ TA1CCTL0 = CCIE; // TACCR0 interrupt enabled TA1CCR0 = 20000; TA1CTL = TASSEL_1; // ACLK, up mode } // Timer A1 interrupt service routine #pragma vector = TIMER1_A0_VECTOR __interrupt void Timer1_A0_ISR(void) { TA1CTL &= ~(MC_3); //stops the Timer LPM3_EXIT; } /******************************************************/
file RF430.h
long temp; void Rf430_I2C_Init(){ //configure eUSCI for I2C UCB0CTL1 |= UCSWRST; //Software reset enabled UCB0CTLW0 |= UCMODE_3 + UCMST + UCSYNC + UCTR; //I2C mode, Master mode, sync, transmitter UCB0CTLW0 |= UCSSEL_2; // SMCLK = 8MHz UCB0BRW = 30; // Baudrate = SMLK/40 = 200kHz UCB0I2CSA = 0x0028; //slave address - determined by pins E0, E1, and E2 on the RF430CL330H UCB0CTL1 &= ~UCSWRST; } void Update_RF430(void) { temp = (RF_ENABLE | INT_ENABLE); Rf430_I2C_Init(); Write_Continuous(26, &FRAM_Message[26], 23); // Writing Record and NDEF Message to RF430 Write_Register(INT_ENABLE_REG, EOR_INT_ENABLE); Write_Register(CONTROL_REG, temp); // Enable RF Write_Register(INT_FLAG_REG, 0); } // Reads the register at reg_addr, returns the result unsigned int Read_Register(unsigned int reg_addr) { TxAddr[0] = reg_addr >> 8; // MSB of address TxAddr[1] = reg_addr & 0xFF; // LSB of address UCB0CTLW1 = UCASTP_1; UCB0TBCNT = 0x0002; UCB0CTL1 &= ~UCSWRST; UCB0CTL1 |= UCTXSTT + UCTR; // Start i2c write operation while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[0]; while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[1]; while(!(UCB0IFG & UCBCNTIFG)); UCB0CTL1 &= ~UCTR; // I2C read operation UCB0CTL1 |= UCTXSTT; // Repeated start while(!(UCB0IFG & UCRXIFG0)); RxData[0] = UCB0RXBUF; UCB0CTLW0 |= UCTXSTP; // Send stop after next RX while(!(UCB0IFG & UCRXIFG0)); RxData[1] = UCB0RXBUF; while (!(UCB0IFG & UCSTPIFG)); // Ensure stop condition got sent UCB0CTL1 |= UCSWRST; return RxData[1] << 8 | RxData[0]; } //Continuous read data_length bytes and store in the area "read_data" void Read_Continuous(unsigned int reg_addr, unsigned char* read_data, unsigned int data_length) { unsigned int i; TxAddr[0] = reg_addr >> 8; // MSB of address TxAddr[1] = reg_addr & 0xFF; // LSB of address UCB0CTLW1 = UCASTP_1; UCB0TBCNT = 0x0002; UCB0CTL1 &= ~UCSWRST; UCB0CTL1 |= UCTXSTT + UCTR; // Start i2c write operation while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[0]; while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[1]; while(!(UCB0IFG & UCBCNTIFG)); UCB0CTL1 &= ~UCTR; //i2c read operation UCB0CTL1 |= UCTXSTT; //repeated start while(!(UCB0IFG & UCRXIFG0)); for(i = 0; i < data_length-1; i++) { while(!(UCB0IFG & UCRXIFG0)); read_data[i] = UCB0RXBUF; if(i == data_length-1) UCB0CTL1 |= UCTXSTP; //send stop after next RX } UCB0CTLW0 |= UCTXSTP; //send stop after next RX while(!(UCB0IFG & UCRXIFG0)); read_data[i] = UCB0RXBUF; while (!(UCB0IFG & UCSTPIFG)); // Ensure stop condition got sent UCB0CTL1 |= UCSWRST; } //writes the register at reg_addr with value void Write_Register(unsigned int reg_addr, unsigned int value) { TxAddr[0] = reg_addr >> 8; // MSB of address TxAddr[1] = reg_addr & 0xFF; // LSB of address TxData[0] = value >> 8; TxData[1] = value & 0xFF; UCB0CTLW1 = UCASTP_1; UCB0TBCNT = 0x0004; UCB0CTL1 &= ~UCSWRST; UCB0CTL1 |= UCTXSTT + UCTR; // Start i2c write operation //write the address while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[0]; while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[1]; //write the data while(!(UCB0IFG & UCTXIFG0)); //UCB0TXBUF = TxData[0]; UCB0TXBUF = TxData[1]; while(!(UCB0IFG & UCTXIFG0)); //UCB0TXBUF = TxData[1]; UCB0TXBUF = TxData[0]; while (!(UCB0IFG & UCBCNTIFG)); UCB0CTL1 |= UCTXSTP; while (!(UCB0IFG & UCSTPIFG)); // Ensure stop condition got sent UCB0CTL1 |= UCSWRST; } //writes the register at reg_addr and incrementing addresses with the data at "write_data" of length data_length void Write_Continuous(unsigned int reg_addr, unsigned char* write_data, unsigned int data_length) { unsigned int i; TxAddr[0] = reg_addr >> 8; //MSB of address TxAddr[1] = reg_addr & 0xFF; //LSB of address UCB0CTLW1 = UCASTP_1; UCB0TBCNT = data_length; //data_length is in words, TBCNT is in bytes, so multiply by 2 UCB0CTL1 &= ~UCSWRST; UCB0CTL1 |= UCTXSTT + UCTR; //start i2c write operation //write the address while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[0]; while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = TxAddr[1]; //write the data for(i = 0; i < data_length; i++) { while(!(UCB0IFG & UCTXIFG0)); UCB0TXBUF = write_data[i]; } while(!(UCB0IFG & UCTXIFG0)); while (!(UCB0IFG & UCBCNTIFG)); UCB0CTL1 |= UCTXSTP; while (!(UCB0IFG & UCSTPIFG)); // Ensure stop condition got sent UCB0CTL1 |= UCSWRST; }
Any idea of what can I be doing wrong? Please let me know :)