Other Parts Discussed in Thread: C2000WARE
Tool/software:
Hello,
I find the example for HDC3020 sensor from this post here
Do you have example how to use C2000 to interact with HDC3020 sensor?
Thanks!
Crane
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi Crane,
Unfortunately we do not have example code to use HDC3020 with C2000. The ASCStudio link in the previous post you linked is your best bet, that is C code that you can adapt to whatever MCU you are using.
Thanks
-Alex Thompson
Hi Alex,
Reading ID is fine.
But once reading data is added, temperature and humidity can be read correctly once or twice (read data every second) right after the program starts, then the result of check bus status always return ERROR_BUS_BUSY before submitting command.
Below are the functions I am using to submit data:
uint16_t I2C_TransmitSlaveAddress_ControlBytes(struct I2CHandle *I2C_Params) { uint16_t status, attemptCount=1; uint32_t base = I2C_Params->base; status = 1; while(status & (attemptCount <= I2C_Params->NumOfAttempts)) { status = checkBusStatus(base); attemptCount++; DEVICE_DELAY_US(I2C_Params->Delay_us); } if(status) { uPrintf("\tTC1%X", status); return status; } I2C_setConfig(base, (I2C_MASTER_SEND_MODE|I2C_REPEAT_MODE)); if((I2C_Params->SlaveAddr) > MAX_7_BIT_ADDRESS) { //10-bit addressing I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS); } // Setup slave address I2C_setSlaveAddress(base, I2C_Params->SlaveAddr); ndrvdebugPrintf("Salve address: %d\0", "", I2C_Params->SlaveAddr, 0, 0); int16_t i; uint32_t temp = *(I2C_Params->pControlAddr); for(i=I2C_Params->NumOfAddrBytes-1;i>=0;i--) { I2C_putData(base, (temp >> (i*8U)) & 0xFF); ndrvdPrintf("| %d\0", "", (temp >> (i*8U)) & 0xFF, 0, 0); } I2C_sendStartCondition(base); DEVICE_DELAY_US(150U); status = handleNACK(base); if(status) { if(attemptCount <= (I2C_Params->NumOfAttempts)) { attemptCount++; I2C_setConfig(base, (I2C_MASTER_SEND_MODE)); I2C_sendStartCondition(base); DEVICE_DELAY_US(I2C_Params->Delay_us); } else { uPrintf(" | TC2%X", status); return status; } } attemptCount = 1; while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_Params->NumOfAddrBytes + 2U)) { status = handleNACK(base); if(status) { uPrintf("| TC3%X", status); return status; } attemptCount++; DEVICE_DELAY_US(I2C_Params->Delay_us); } return SUCCESS; } /* Function to transmit the data store in the transmit buffer */ uint16_t I2C_MasterTransmitter(struct I2CHandle *I2C_Params) { uint16_t status, attemptCount; uint32_t base = I2C_Params->base; I2C_disableFIFO(base); I2C_enableFIFO(base); status = I2C_TransmitSlaveAddress_ControlBytes(I2C_Params); if(status) { uPrintf("\tT1%X", status); return status; } I2C_setDataCount(base, (I2C_Params->NumOfAddrBytes + I2C_Params->NumOfDataBytes)); I2C_setFIFOInterruptLevel(base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL); I2C_enableInterrupt(base, I2C_INT_TXFF); uint16_t numofSixteenByte = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL; uint16_t remainingBytes = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL; uint16_t i,count = 0,buff_pos=0; while(count < numofSixteenByte) { for(i=1;i<=I2C_FIFO_LEVEL;i++) { I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]); } attemptCount = 1; while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_FIFO_LEVEL + 2U)) { status = handleNACK(base); if(status) { uPrintf(" | T2%X", status); return status; } attemptCount++; DEVICE_DELAY_US(I2C_Params->Delay_us); } count++; } for (i=0; i < remainingBytes; i++) { //uint16_t temp; temp = I2C_Params->pTX_MsgBuffer[buff_pos]; I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]); ndrvdebugPrintf("Transmit data: %d\0", "", temp, 0, 0); } attemptCount = 1; while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (remainingBytes + 2U)) { status = handleNACK(base); if(status) { uPrintf(" | T3%X", status); return status; } attemptCount++; DEVICE_DELAY_US(I2C_Params->Delay_us); } I2C_sendStopCondition(base); attemptCount = 1; while(I2C_getStopConditionStatus(base) && (attemptCount <= I2C_Params->NumOfAttempts)) { DEVICE_DELAY_US(I2C_Params->Delay_us); attemptCount++; } return SUCCESS; }
What might be the cause or any suggestions on what to check?
Thanks!
Crane
Crane,
Are you setting the automatic measurement command 0x2130, then 0xE000 to read the data every second as it updates? Are you trying to NACK the final CRC on the 6-byte read? If so, that does not work. When the bus sends you that message, it would be helpful if you could confirm that the device is NACKing or not.
Thanks
-Alex Thompson
Alex,
No, I am using the way the device is configured in the example code. Haven't tried any other measurement method yet.
Other than providing mcu_i2ctransfer(), everything else is using the example code.
Regards,
Crane
It works fine to read three bytes for temperature or humidity respectively. Not working to read 6 bytes to get them together. Always get bus busy error when reading 6 bytes.
Is this the case you mentioned? What do you mean " trying to NACK the final CRC on the 6-byte read"?
Thanks!
Crane
Crane,
This issue is most likely stemming from an error in I2C implementation on the C2000. I am going to reassign this post to the C2000 E2E team so they can help you with implementing the I2C correctly on the MCU.
Regards
-Alex Thompson
Crane,
Could you please provide the configurations used to send and NACK the data? C2000 I2C reads and writes data one byte at a time typically. In order to read more than that at a time, there are functions that can be modified for your use case in the provided in the C2000WARE I2C EEPROM examples and I2C Driverlib.
Best Regards,
Aishwarya
Hi Aishwarya,
Here are the function to transmit:
uint16_t I2C_MasterTransmitter(struct I2CHandle *I2C_Params) { uint16_t status, attemptCount; uint32_t base = I2C_Params->base; I2C_disableFIFO(base); I2C_enableFIFO(base); status = I2C_TransmitSlaveAddress_ControlBytes(I2C_Params); if(status) { nuPrintf("\tT1%X", status); return status; } I2C_setDataCount(base, (I2C_Params->NumOfAddrBytes + I2C_Params->NumOfDataBytes)); I2C_setFIFOInterruptLevel(base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL); I2C_enableInterrupt(base, I2C_INT_TXFF); uint16_t numofSixteenByte = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL; uint16_t remainingBytes = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL; uint16_t i,count = 0,buff_pos=0; while(count < numofSixteenByte) { for(i=1;i<=I2C_FIFO_LEVEL;i++) { I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]); } attemptCount = 1; while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_FIFO_LEVEL + 2U)) { status = handleNACK(base); if(status) { nuPrintf(" | T2%X", status); return status; } attemptCount++; DEVICE_DELAY_US(I2C_Params->Delay_us); } count++; } for (i=0; i < remainingBytes; i++) { //uint16_t temp; temp = I2C_Params->pTX_MsgBuffer[buff_pos]; I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]); ndrvdebugPrintf("Transmit data: %d\0", "", temp, 0, 0); } attemptCount = 1; while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (remainingBytes + 2U)) { status = handleNACK(base); if(status) { nuPrintf(" | T3%X", status); return status; } attemptCount++; DEVICE_DELAY_US(I2C_Params->Delay_us); } I2C_sendStopCondition(base); attemptCount = 1; while(I2C_getStopConditionStatus(base) && (attemptCount <= I2C_Params->NumOfAttempts)) { DEVICE_DELAY_US(I2C_Params->Delay_us); attemptCount++; } return SUCCESS; }
Here is the function to receive:
uint16_t I2C_MasterReceiver(struct I2CHandle *I2C_Params) { uint16_t status; uint16_t attemptCount; uint32_t base = I2C_Params->base; I2C_disableFIFO(base); I2C_enableFIFO(base); status = I2C_TransmitSlaveAddress_ControlBytes(I2C_Params); if(status) { return status; } uint16_t numofSixteenByte = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL; uint16_t remainingBytes = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL; I2C_setConfig(base, (I2C_MASTER_RECEIVE_MODE|I2C_REPEAT_MODE)); I2C_sendStartCondition(base); uint16_t i,count = 0,buff_pos=0; while(count < numofSixteenByte) { status = handleNACK(base); if(status) { return status; } count++; attemptCount = 1; while(!(I2C_getRxFIFOStatus(base) == I2C_FIFO_RXFULL) && attemptCount <= 9 * (I2C_FIFO_RXFULL + 2U)) { DEVICE_DELAY_US(I2C_Params->Delay_us); attemptCount++; } for(i=0; i<I2C_FIFO_LEVEL; i++) { I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base); } } attemptCount = 1; while(!(I2C_getRxFIFOStatus(base) == remainingBytes) && attemptCount <= 9 * (remainingBytes + 2U)) { DEVICE_DELAY_US(I2C_Params->Delay_us); attemptCount++; } I2C_sendStopCondition(base); for(i=0; i<remainingBytes; i++) { I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base); } status = handleNACK(base); if(status) { return status; } I2C_disableFIFO(base); attemptCount = 1; while(I2C_getStopConditionStatus(base) && (attemptCount <= I2C_Params->NumOfAttempts)) { DEVICE_DELAY_US(I2C_Params->Delay_us); attemptCount++; } return SUCCESS; }
Are these what you are looking for?
Thanks!
Crane
Crane,
Have you referred to the (3) available I2C EEPROM examples in C2000WARE? Even though they are using EEPROMs, the examples can be modified to be used with the sensor.
Assuming that the 'I2C_TransmitSlaveAddress_ControlBytes' is for checking the status of the HDC3020. In controller transmitter mode, on line 18, I would use the 'I2C_setDataCount' function once for setting up the sensor address and once for the data bytes instead of doing it in one go like this in the EEPROM example:
In controller receiver mode, why have you not enabled the RX interrupt like you have for controller transmitter with the TX interrupt?
In general, this table is helpful to understand bus activity for controller modes.
Best Regards,
Aishwarya
Hi Aishwarya,
I am not sure how this is relevant to the issue I am facing.
This is the issue:
It works fine to read three bytes for temperature or humidity respectively. Not working to read 6 bytes to get them together. Always get bus busy error when reading 6 bytes.
Thanks!
Crane
Crane,
Could you use a logic analyzer to confirm if you are seeing an ACK/NACK every byte, specifically after the third byte and send that screenshot. If these are not set, then the bus will show to be busy and not continue operations.
What are the TX / RX FIFO levels set to? It is possible that there is an under flow or overflow. You can share your initial I2C configurations.
Are you seeing that the SCL is stuck low (indicative of clock stretching and the target is holding it low).
Can the target device do a continuous 6-byte read (assuming yes)?
Best Regards,
Aishwarya