Other Parts Discussed in Thread: ADS112C04
Hello,
I am trying to read data from a ADS112C04. Therefore I have written functions that basically work like corresponding functions from eusci_b_i2c library but with repeated start conditions. The initialisation of the ADC works fine and I can write all the registers, the IDAC current will be switched on and the PGA also works. I am also receiving the first measurement correctly. But when sending the RDATA command for the second measurement the code gets stuck.
The measurement is triggered by TimerB four times per second and this is the complete sequence:
TimerB Interrupt -> Send START_SYNC Command (function ADS112C04_Measure) -> DRDY falling edge IRQ -> Send RDATA and switch to receive (see function ADS112C04_receive) -> I2C RX IRQ -> process measurement data
This cycle works one time in the beginning and gets stuck the second time (see source):
bool ADS112C04_init(void)//(uint8_t eUSCI_MODULE) { uint8_t i; const uint16_t delay = 80; const uint8_t regSend[8] = {CMD_WREG0, REG0, CMD_WREG1, REG1, CMD_WREG2, REG2, CMD_WREG3, REG3}; // I2C_ Init EUSCI_B_I2C_initMasterParam i2c_master_init = { EUSCI_B_I2C_CLOCKSOURCE_SMCLK, CS_getSMCLK(), EUSCI_B_I2C_SET_DATA_RATE_100KBPS, 0, EUSCI_B_I2C_NO_AUTO_STOP }; ADS112C04_powerOn(); EUSCI_B_I2C_initMaster(AFE_USCI_BASE, &i2c_master_init); EUSCI_B_I2C_clearInterrupt(AFE_USCI_BASE, UCRXIE); // neu EUSCI_B_I2C_setSlaveAddress(AFE_USCI_BASE, ADS112C04_ADDRESS); EUSCI_B_I2C_setMode(AFE_USCI_BASE,EUSCI_B_I2C_TRANSMIT_MODE); EUSCI_B_I2C_enable(AFE_USCI_BASE); HWREG16(AFE_USCI_BASE + OFS_UCBxCTLW0) |= UCTXSTT; while(HWREG16(AFE_USCI_BASE + OFS_UCBxCTLW0) & UCTXSTT); for (i=0; i<8; i++) { HWREG16(AFE_USCI_BASE + OFS_UCBxTXBUF) = regSend[i]; while ((!(HWREG16(AFE_USCI_BASE + OFS_UCBxIFG) & UCTXIFG)) && --timeout); if (timeout == 0) return (STATUS_FAIL); __delay_cycles(delay); } HWREG16(AFE_USCI_BASE + OFS_UCBxCTLW0) |= UCTXSTP; EUSCI_B_I2C_clearInterrupt(AFE_USCI_BASE, UCRXIE); EUSCI_B_I2C_enableInterrupt(AFE_USCI_BASE, UCRXIE); GPIO_selectInterruptEdge(AFE_EOC_PIN, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_clearInterrupt(AFE_EOC_PIN); GPIO_enableInterrupt(AFE_EOC_PIN); return (STATUS_SUCCESS); } bool ADS112C04_sendCmd(uint8_t command) { bool timeoutError = false; if (!EUSCI_B_I2C_masterSendSingleByteWithTimeout(AFE_USCI_BASE, command, ADS112C04_TIMEOUT)) return (STATUS_FAIL); return (STATUS_SUCCESS); } bool ADS112C04_measure(void) { bool error = false; error = ADS112C04_sendCmd(CMD_START_SYNC); return (error); } bool ADS112C04_receive(void) // RDATA { uint32_t timeout = ADS112C04_TIMEOUT; uint16_t txieStatus = HWREG16(AFE_USCI_BASE + OFS_UCBxIE) & UCTXIE; //Store current transmit interrupt enable HWREG16(AFE_USCI_BASE + OFS_UCBxIE) &= ~(UCTXIE); //Disable transmit interrupt enable HWREG16(AFE_USCI_BASE + OFS_UCBxCTLW0) |= UCTR + UCTXSTT; //Send start condition. while ((!(HWREG16(AFE_USCI_BASE + OFS_UCBxIFG) & UCTXIFG)) && --timeout); //Poll for transmit interrupt flag if (timeout == 0) return (STATUS_FAIL); //Check if transfer timed out HWREG16(AFE_USCI_BASE + OFS_UCBxTXBUF) = CMD_RDATA;//Send single byte data timeout = ADS112C04_TIMEOUT; //Reset timeout /* !!!!!!! THE CODE GETS STUCK IN THE LOOP BELOW !!!!!!!! */ while ((!(HWREG16(AFE_USCI_BASE + OFS_UCBxIFG) & UCTXIFG)) && --timeout);//Poll for transmit interrupt flag. if (timeout == 0) return (STATUS_FAIL); //Check if transfer timed out HWREG16(AFE_USCI_BASE + OFS_UCBxIFG) &= ~(UCTXIFG); //Clear transmit interrupt flag before enabling interrupt again HWREG16(AFE_USCI_BASE + OFS_UCBxIE) |= txieStatus;//Reinstate transmit interrupt enable __delay_cycles(64); // Receive bytesExpected = 2; i2cRxByteCount = 0; EUSCI_B_I2C_setMode(AFE_USCI_BASE, EUSCI_B_I2C_RECEIVE_MODE); HWREG16(AFE_USCI_BASE + OFS_UCBxCTLW0) |= UCTXSTT; // Start return(STATUS_SUCCESS); } #pragma vector = AFE_IRQ_VECT __interrupt void EUSCI_B_ISR(void) { switch(__even_in_range(AFE_IRQ_REG, USCI_I2C_UCBIT9IFG)) //NEU { case USCI_NONE: break; // Vector 0: No interrupts case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG case USCI_I2C_UCNACKIFG: break; // Vector 4: NACKIFG 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 (bytesExpected > 0) { if (i2cRxByteCount == bytesExpected - 1) { // EUSCI_B_I2C_masterReceiveMultiByteFinish HWREG16(AFE_USCI_BASE + OFS_UCBxCTLW0) |= UCTXSTP; // Stop-Bedingung setzen } i2cRxBuf[i2cRxByteCount] = HWREG16(AFE_USCI_BASE + OFS_UCBxRXBUF); i2cRxByteCount++; if (i2cRxByteCount == bytesExpected) { bytesExpected = 0; i2cRxFlag = true; __bic_SR_register_on_exit(LPM3_bits | GIE); } } break; case USCI_I2C_UCTXIFG0: break; // Vector 24: TXIFG0 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; } }