Hi,
I am trying to build some simple routines upon the Driverlib library to send and receive data over I2C channel using interrupts.
The available examples are for transmit or receive only, so I attempted a merge of the interrupt routines, without full success.
It looks like the Tx portion works well, but I cannot manage to make the receive portion wrok as well.
Here is my interrupt routine:
#pragma vector=USCI_B0_VECTOR __interrupt void USCIB0_ISR(void) { switch(__even_in_range(UCB0IV, 0x1E)) { case 0x00: break; // Vector 0: No interrupts break; case 0x02: break; // Vector 2: ALIFG break; case 0x04: // Vector 4: NACKIFG break; EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE); Ptr = 0; break; case 0x06: break; // Vector 6: STT IFG break; case 0x08: break; // Vector 8: STPIFG break; case 0x0a: break; // Vector 10: RXIFG3 break; case 0x0c: break; // Vector 14: TXIFG3 break; case 0x0e: break; // Vector 16: RXIFG2 break; case 0x10: break; // Vector 18: TXIFG2 break; case 0x12: break; // Vector 20: RXIFG1 break; case 0x14: break; // Vector 22: TXIFG1 break; case 0x16: // Vector 24: RXIFG0 break; if(Ptr) { *Ptr++ = EUSCI_B_I2C_masterReceiveSingle(EUSCI_B0_BASE); // Get RX data if(--Cnt == 0) { EUSCI_B_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE); Ptr = 0; } } break; case 0x18: // Vector 26: TXIFG0 break; if(Cnt) // Check TX byte counter { EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, *Ptr++); Cnt--; // Decrement TX byte counter } else { EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE); Ptr = 0; } break; case 0x1c: break; // Vector 30: clock low timeout break; case 0x1e: break; // Vector 32: 9th bit break; default: break; } }
The code to start a reception is:
void I2C_Sen_Read(int len, char * buf) { EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, addr); EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE); EUSCI_B_I2C_enable(EUSCI_B0_BASE); Cnt = len; Ptr = buf; EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT); EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT); EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE); }
The Ptr variable is used to point to the buffer but also as an indication that the reception (or transmission) is complete.
The problem is that I see with a scope a train of clock pulses corresponding to one byte more than expected (i.e. I see two 8 bit+ack pulses if I ask for one byte read.
But the major problem is that the SDA and SCL lines remain low. It looks like the EUSCI_B_I2C_masterReceiveMultiByteStop is doing nothing.
Can someone help me?
Thank you.
Regards.
Mau.