Anonymous
Not applicable
Dec 26, 2013
05:44 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 26, 2013
05:44 PM
I have an I2C device, LM73 TEMP SENSOR. http://www.ti.com/product/lm73
I have connected it on I2C bus, multiplex with on-board EEPROM, they share the I2C bus together.
After connection established, download application firmware is failure.
After I remove LM73, downloading is ok.
Downloading log is enable, they are below.
Solved! Go to Solution.
Labels
- Labels:
-
I2C
1 Solution
Jan 08, 2014
05:18 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 08, 2014
05:18 PM
The firmware team has a similar setup available with an LM73 connected.They are also using 0x48 << 1 as the slave address and it appears that everything is working correctly.The debug trace shown below occurs when initializing and then reading the temperature once per second:GPIO_WP:OFF=0temperature_sensor_create()GattDB:20b990, 20b9d4hdl: perm:len:maxlen:uuid0001:02:02:02:280001 180014:02:02:02:280000 180015:02:05:05:280302 16 00 00 2a0016:02:10:10:2a0054 65 6d 70 20 73 65 6e 73 6f 72 00 00 00 00 000017:02:05:05:280302 18 00 01 2a0018:02:02:02:2a0100 02GattDB completeReading identification register...Temperature sensor identified as Manuf: 1, Prod: 9, Rev: 0…temperature_sensor_read_temperature_data returned 3104The current temperature is: 24 & 1/4 degrees CStarting new temperature measurement.Sensor read status returned E9temperature_sensor_read_temperature_data returned 3156The current temperature is: 24 & 21/32 degrees CStarting new temperature measurement.Sensor read status returned E9temperature_sensor_read_temperature_data returned 3160The current temperature is: 24 & 11/16 degrees CStarting new temperature measurement.Sensor read status returned E9temperature_sensor_read_temperature_data returned 3156The current temperature is: 24 & 21/32 degrees C…Per the last post, I confirmed also that the btp file is in Platforms/BCM920732TAG_Q32/ and that all GPIOs are input enabled by default. However, you cannot use GPIO to drive the sensor as you will need to use a transistor switch to control power to the sensor. Here, you want to use a transistor whose input is tied in such a way that it is turned off. Then, when the FW boots up, the app should drive its GPIO to turn on the switch, which will in turn power the temperature sensor. We don’t have a TSL2550 to test, but have seen no problems with the LM73 temperature sensor during download to EEPROM. If the LM73 is not acking, then it could be that the address you are using in the code and the address configured for the LM73 are not the same. If the app uses 0x48, then the part has to be an LM73-0 part with the address pin left floating. The sensor has other address options that you can try (like tying the address pin to Vdd or GND). Take a look at this latest setup of feedback and let me know if you are able to resolve the issue.
11 Replies
Dec 27, 2013
07:17 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 27, 2013
07:17 AM
Firmware downloads occur over the HCI UART, so Im not sure why the I2C interface is causing problems with downloads.Im assuming that physical pin 21 on the 20732S module is being used for SCL (I2C clock to ext. device) and pin 22 for SDA (I2C data to ext. device) and that there is no external termination (both pins are internal PUs on the module).In addition: Transaction length of 16 bytes, maximum SCL speed of 4000 kbps, its the only master on the bus and the sensor supports a 7-bit slave address?The following code snippet shows how to initialize I2C in the master role, and how to write, read and use the combo write-then-read transaction using the driver API available in the WICED SDK.Are you using this code snippet provided within the WICED Smart Hardware Interfaces Guide thats available here on the website?#include "cfa.h"// Use slave address 0x1A = (7b0001101 << 1) | 1bR|W.#define I2C_SLAVE_ADDRESS (0x1A)// Read operation to the lower level driver is 0.#define I2C_SLAVE_OPERATION_READ 0// Write operation to the lower level driver is 1.#define I2C_SLAVE_OPERATION_WRITE 1// Reads data from the slave into the given buffer.// buffer - The buffer into which to read. Should be allocated by caller.// length - The number of bytes to read form the slave.// slave_address - The address of the slave device. Valid bits are the// upper 7 bits, bit 0 must be 1b0.// Returns 1 if successful, else 0.//UINT8 i2cm_read_from_slave(BYTE* buffer, UINT32 length, UINT8 slave_address){// Assume failure.UINT8 return_value = 0;// Invoke the lower level driver. Non-combo transaction, so set offset parameters to NULL/0.CFA_BSC_STATUS read_status = cfa_bsc_OpExtended(buffer, length, NULL, 0, slave_address,I2C_SLAVE_OPERATION_READ);switch(read_status){case CFA_BSC_STATUS_INCOMPLETE:// Transaction did not go through. ERROR. Handle this case.break;case CFA_BSC_STATUS_SUCCESS:// The read was successful.return_value = 1;break;case CFA_BSC_STATUS_NO_ACK:// No slave device with this address exists on the I2C bus. ERROR. Handle this.default:break;}return return_value;}// Writes data to the slave from the given buffer.// buffer - The buffer that has the data to be written to the slave.// length - The number of bytes to write to slave.// slave_address - The address of the slave device. Valid bits are the// upper 7 bits, bit 0 must be 1b0.// Return 1 if successful, else 0.//UINT8 i2cm_write_to_slave(BYTE* buffer, UINT32 length, UINT8 slave_address){// Assume failure.UINT8 return_value = 0;// Invoke the lower level driver. Non-combo transaction, so set offset parameters to NULL/0.CFA_BSC_STATUS read_status = cfa_bsc_OpExtended(buffer, length, NULL, 0, slave_address, I2C_SLAVE_OPERATION_WRITE);switch(read_status){case CFA_BSC_STATUS_INCOMPLETE:// Transaction did not go through. ERROR. Handle this case.break;case CFA_BSC_STATUS_SUCCESS:// The read was successful.return_value = 1;break;case CFA_BSC_STATUS_NO_ACK:// No slave device with this address exists on the I2C bus. ERROR. Handle this.default:break;}return return_value;}// Combo write-then-read transaction. Writes some bytes to slave,// then issues a repeated START followed by a read transaction.// buffer_to_write - The buffer from which to write to the slave. If the number of// bytes to read exceeds 16, the driver will update this value by the number// of bytes read and start another new transaction until length_to_read number// of bytes have been read. This API is available for devices that behave like// EEPROMs, so the buffer has to point to an array of bytes with the offset// address in big endian format. See any I2C EEPROM specification for details.// length_of_write - The number of bytes that buffer_to_write pointes to. This is// also the number of bytes in the first WRITE transaction before the repeated// start. Note that length_of_write + length_to_read has to be <= 16, typically// is 2 for EEPROMs because they use 16 bit offsets.// buffer_to_read_into - The buffer into which the data is to be read during the READ// part of the combo transaction (after the repeated START condition).// length_to_read - The number of bytes to read during the READ portion of the combo// transaction. Note that length_of_write + length_to_read has to be <= 16,// typically is 2 for EEPROMs because they use 16 bit offsets.// slave_address - The address of the slave device. Valid bits are the// upper 7 bits, bit 0 must be 1b0.// Returns 1 if successful, else 0.//UINT8 i2cm_write_then_read_from_slave(BYTE* buffer_to_write, UINT32 length_of_write,BYTE* buffer_to_read_into, UINT32 length_to_read,UINT8 slave_address){// Assume failure.UINT8 return_value = 0;// Invoke the lower level driver. This is a combo transaction.CFA_BSC_STATUS read_status = cfa_bsc_OpExtended(buffer_to_read_into, length_to_read, buffer_to_write,length_of_write, slave_address,I2C_SLAVE_OPERATION_READ);switch(read_status){case CFA_BSC_STATUS_INCOMPLETE:// Transaction did not go through. ERROR. Handle this case.break;case CFA_BSC_STATUS_SUCCESS:// The read was successful.return_value = 1;break;case CFA_BSC_STATUS_NO_ACK:// No slave device with this address exists on the I2C bus. ERROR. Handle this.default:break;}return return_value;}
Dec 27, 2013
11:01 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 27, 2013
11:01 AM
The HW team thinks that this may be an electrical issue. They also looked at the DS for LM73 and confirmed that the I2C slave address does not collide with the slave address of the EEPROM. Can you measure the levels on SCL and SDA and see what the lines look like during the download?
Anonymous
Not applicable
Dec 29, 2013
04:34 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 29, 2013
04:34 PM
Firmware downloads occur over the HCI UART, so Im not sure why the I2C interface is causing problems with downloads.Im assuming that physical pin 21 on the 20732S module is being used for SCL (I2C clock to ext. device) and pin 22 for SDA (I2C data to ext. device) and that there is no external termination (both pins are internal PUs on the module).In addition: Transaction length of 16 bytes, maximum SCL speed of 4000 kbps, its the only master on the bus and the sensor supports a 7-bit slave address?The following code snippet shows how to initialize I2C in the master role, and how to write, read and use the combo write-then-read transaction using the driver API available in the WICED SDK.Are you using this code snippet provided within the WICED Smart Hardware Interfaces Guide thats available here on the website?#include "cfa.h"// Use slave address 0x1A = (7b0001101 << 1) | 1bR|W.#define I2C_SLAVE_ADDRESS (0x1A)// Read operation to the lower level driver is 0.#define I2C_SLAVE_OPERATION_READ 0// Write operation to the lower level driver is 1.#define I2C_SLAVE_OPERATION_WRITE 1// Reads data from the slave into the given buffer.// buffer - The buffer into which to read. Should be allocated by caller.// length - The number of bytes to read form the slave.// slave_address - The address of the slave device. Valid bits are the// upper 7 bits, bit 0 must be 1b0.// Returns 1 if successful, else 0.//UINT8 i2cm_read_from_slave(BYTE* buffer, UINT32 length, UINT8 slave_address){// Assume failure.UINT8 return_value = 0;// Invoke the lower level driver. Non-combo transaction, so set offset parameters to NULL/0.CFA_BSC_STATUS read_status = cfa_bsc_OpExtended(buffer, length, NULL, 0, slave_address,I2C_SLAVE_OPERATION_READ);switch(read_status){case CFA_BSC_STATUS_INCOMPLETE:// Transaction did not go through. ERROR. Handle this case.break;case CFA_BSC_STATUS_SUCCESS:// The read was successful.return_value = 1;break;case CFA_BSC_STATUS_NO_ACK:// No slave device with this address exists on the I2C bus. ERROR. Handle this.default:break;}return return_value;}// Writes data to the slave from the given buffer.// buffer - The buffer that has the data to be written to the slave.// length - The number of bytes to write to slave.// slave_address - The address of the slave device. Valid bits are the// upper 7 bits, bit 0 must be 1b0.// Return 1 if successful, else 0.//UINT8 i2cm_write_to_slave(BYTE* buffer, UINT32 length, UINT8 slave_address){// Assume failure.UINT8 return_value = 0;// Invoke the lower level driver. Non-combo transaction, so set offset parameters to NULL/0.CFA_BSC_STATUS read_status = cfa_bsc_OpExtended(buffer, length, NULL, 0, slave_address, I2C_SLAVE_OPERATION_WRITE);switch(read_status){case CFA_BSC_STATUS_INCOMPLETE:// Transaction did not go through. ERROR. Handle this case.break;case CFA_BSC_STATUS_SUCCESS:// The read was successful.return_value = 1;break;case CFA_BSC_STATUS_NO_ACK:// No slave device with this address exists on the I2C bus. ERROR. Handle this.default:break;}return return_value;}// Combo write-then-read transaction. Writes some bytes to slave,// then issues a repeated START followed by a read transaction.// buffer_to_write - The buffer from which to write to the slave. If the number of// bytes to read exceeds 16, the driver will update this value by the number// of bytes read and start another new transaction until length_to_read number// of bytes have been read. This API is available for devices that behave like// EEPROMs, so the buffer has to point to an array of bytes with the offset// address in big endian format. See any I2C EEPROM specification for details.// length_of_write - The number of bytes that buffer_to_write pointes to. This is// also the number of bytes in the first WRITE transaction before the repeated// start. Note that length_of_write + length_to_read has to be <= 16, typically// is 2 for EEPROMs because they use 16 bit offsets.// buffer_to_read_into - The buffer into which the data is to be read during the READ// part of the combo transaction (after the repeated START condition).// length_to_read - The number of bytes to read during the READ portion of the combo// transaction. Note that length_of_write + length_to_read has to be <= 16,// typically is 2 for EEPROMs because they use 16 bit offsets.// slave_address - The address of the slave device. Valid bits are the// upper 7 bits, bit 0 must be 1b0.// Returns 1 if successful, else 0.//UINT8 i2cm_write_then_read_from_slave(BYTE* buffer_to_write, UINT32 length_of_write,BYTE* buffer_to_read_into, UINT32 length_to_read,UINT8 slave_address){// Assume failure.UINT8 return_value = 0;// Invoke the lower level driver. This is a combo transaction.CFA_BSC_STATUS read_status = cfa_bsc_OpExtended(buffer_to_read_into, length_to_read, buffer_to_write,length_of_write, slave_address,I2C_SLAVE_OPERATION_READ);switch(read_status){case CFA_BSC_STATUS_INCOMPLETE:// Transaction did not go through. ERROR. Handle this case.break;case CFA_BSC_STATUS_SUCCESS:// The read was successful.return_value = 1;break;case CFA_BSC_STATUS_NO_ACK:// No slave device with this address exists on the I2C bus. ERROR. Handle this.default:break;}return return_value;}I use 920732SPI-AN100-RDS.pdf to initial I2C bus. I connect two I2C device on bus, one is LM73, the other is TSL2550, light sensor. I can read ADC value from TSL2550, but I cant read value from LM73 because LM73 need a write_then_read operation, the writing operation always get return of CFA_BSC_STATUS_NO_ACK.I can provide oscilloscope screen shot if you want.
Anonymous
Not applicable
Dec 29, 2013
04:39 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 29, 2013
04:39 PM
The HW team thinks that this may be an electrical issue. They also looked at the DS for LM73 and confirmed that the I2C slave address does not collide with the slave address of the EEPROM. Can you measure the levels on SCL and SDA and see what the lines look like during the download?Mike,The TAG can be detected and found, the downloading operation can be started. But after a while, downloading is failure and eclipse show that need reset and retry again.I have watched the SCL and SDA state when downloading, I think that bootloader should write something when downloading. The level on SCL and SDA is ok.I enable the downloading log, but forum dont permit to upload it, I will send them using email.
Dec 29, 2013
08:49 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 29, 2013
08:49 PM
I will look into this with the firmware team and see if they can provide some direction.
Jan 02, 2014
03:43 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 02, 2014
03:43 PM
I spoke to the firmware team and heres the feedback they provided based on the files you provided.In the failure case, there is a 1 bit error (0x06 was seen when 0x46 was expected
Anonymous
Not applicable
Jan 07, 2014
06:30 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 07, 2014
06:30 PM
#if 0 //LM73 buff[0] = 0x07; // write command register of LM73, CHIP_ID register status = i2cm_write_to_slave( buff, 1, I2C_LM73_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "W0:0x%02X ", buff[0] ); // Then, read CHIP_ID register status = i2cm_read_from_slave(buff, 2, I2C_LM73_SLAVE_ADDRESS ); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "R0:0x%02X ", buff[0] ); ble_trace1( "R1:0x%02X ", buff[1] ); // write command register, CHIP_ID register, then perform write_then_read, one shot mode wb = 0x07; status = i2cm_write_then_read_from_slave(&wb, sizeof(UINT8), rb, 2, I2C_LM73_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "rb0:0x%02X ", rb[0] ); ble_trace1( "rb1:0x%02X ", rb[1] );#else //TSL2550 buff[0] = 0x43; // select ADC0 register of TSL2550 status = i2cm_write_to_slave( buff, 1, I2C_TSL2550_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "W0:0x%02X ", buff[0] ); // Then, read ADC0 register status = i2cm_read_from_slave(buff, 2, I2C_TSL2550_SLAVE_ADDRESS ); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "R0:0x%02X ", buff[0] ); ble_trace1( "R1:0x%02X ", buff[1] ); // select ADC1 register of TSL2550, then perform write_then_read, one shot mode wb = 0x83; status = i2cm_write_then_read_from_slave(&wb, sizeof(UINT8), rb, 2, I2C_TSL2550_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "rb0:0x%02X ", rb[0] ); ble_trace1( "rb1:0x%02X ", rb[1] );#endif
Anonymous
Not applicable
Jan 07, 2014
06:40 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 07, 2014
06:40 PM
#if 0 //LM73 buff[0] = 0x07; // write command register of LM73, CHIP_ID register status = i2cm_write_to_slave( buff, 1, I2C_LM73_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "W0:0x%02X ", buff[0] ); // Then, read CHIP_ID register status = i2cm_read_from_slave(buff, 2, I2C_LM73_SLAVE_ADDRESS ); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "R0:0x%02X ", buff[0] ); ble_trace1( "R1:0x%02X ", buff[1] ); // write command register, CHIP_ID register, then perform write_then_read, one shot mode wb = 0x07; status = i2cm_write_then_read_from_slave(&wb, sizeof(UINT8), rb, 2, I2C_LM73_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "rb0:0x%02X ", rb[0] ); ble_trace1( "rb1:0x%02X ", rb[1] );#else //TSL2550 buff[0] = 0x43; // select ADC0 register of TSL2550 status = i2cm_write_to_slave( buff, 1, I2C_TSL2550_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "W0:0x%02X ", buff[0] ); // Then, read ADC0 register status = i2cm_read_from_slave(buff, 2, I2C_TSL2550_SLAVE_ADDRESS ); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "R0:0x%02X ", buff[0] ); ble_trace1( "R1:0x%02X ", buff[1] ); // select ADC1 register of TSL2550, then perform write_then_read, one shot mode wb = 0x83; status = i2cm_write_then_read_from_slave(&wb, sizeof(UINT8), rb, 2, I2C_TSL2550_SLAVE_ADDRESS); ble_trace1( "S0:0x%02X ", status ); ble_trace1( "rb0:0x%02X ", rb[0] ); ble_trace1( "rb1:0x%02X ", rb[1] );#endifThese are the address of two I2C sensor devices.#define I2C_LM73_SLAVE_ADDRESS (0x48 << 1)#define I2C_TSL2550_SLAVE_ADDRESS (0x39 << 1)I have posted the code snippet for you. I used condition compile switch "#if 0" to read two sensor separately.When I read the ADC value of TSL2550 light sensor, everything was ok. i2cm_write_to_slave(), i2cm_read_from_slave() and i2cm_write_then_read_from_slave() returned 0x01, CFA_BSC_STATUS_SUCCESS.When I read the LM73s chip id, issue occur. Writing operation always returned CFA_BSC_STATUS_NO_ACK.Reference: LM73 datasheet: http://www.ti.com/lit/ds/symlink/lm73.pdfTSL2550 datasheet: http://datasheet.octopart.com/TSL2550D-TAOS-datasheet-578390.pdf
Anonymous
Not applicable
Jan 07, 2014
07:01 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 07, 2014
07:01 PM
I spoke to the firmware team and heres the feedback they provided based on the files you provided.In the failure case, there is a 1 bit error (0x06 was seen when 0x46 was expected
Jan 08, 2014
03:57 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 08, 2014
03:57 PM
I believe the btp file my firmware team referred to is the one in the platforms/ BCM920732TAG_Q32 directoryRegarding holding the two devices in reset till the app initializes, I understand that you want to know the GPIO state when the BCM20732 is booting because you believe that you can use the GPIO state to reset the I2C devices and then toggle the GPIO when the application running. I am checking with the team to see if this is a valid approach.
Jan 08, 2014
05:18 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 08, 2014
05:18 PM
The firmware team has a similar setup available with an LM73 connected.They are also using 0x48 << 1 as the slave address and it appears that everything is working correctly.The debug trace shown below occurs when initializing and then reading the temperature once per second:GPIO_WP:OFF=0temperature_sensor_create()GattDB:20b990, 20b9d4hdl: perm:len:maxlen:uuid0001:02:02:02:280001 180014:02:02:02:280000 180015:02:05:05:280302 16 00 00 2a0016:02:10:10:2a0054 65 6d 70 20 73 65 6e 73 6f 72 00 00 00 00 000017:02:05:05:280302 18 00 01 2a0018:02:02:02:2a0100 02GattDB completeReading identification register...Temperature sensor identified as Manuf: 1, Prod: 9, Rev: 0…temperature_sensor_read_temperature_data returned 3104The current temperature is: 24 & 1/4 degrees CStarting new temperature measurement.Sensor read status returned E9temperature_sensor_read_temperature_data returned 3156The current temperature is: 24 & 21/32 degrees CStarting new temperature measurement.Sensor read status returned E9temperature_sensor_read_temperature_data returned 3160The current temperature is: 24 & 11/16 degrees CStarting new temperature measurement.Sensor read status returned E9temperature_sensor_read_temperature_data returned 3156The current temperature is: 24 & 21/32 degrees C…Per the last post, I confirmed also that the btp file is in Platforms/BCM920732TAG_Q32/ and that all GPIOs are input enabled by default. However, you cannot use GPIO to drive the sensor as you will need to use a transistor switch to control power to the sensor. Here, you want to use a transistor whose input is tied in such a way that it is turned off. Then, when the FW boots up, the app should drive its GPIO to turn on the switch, which will in turn power the temperature sensor. We don’t have a TSL2550 to test, but have seen no problems with the LM73 temperature sensor during download to EEPROM. If the LM73 is not acking, then it could be that the address you are using in the code and the address configured for the LM73 are not the same. If the app uses 0x48, then the part has to be an LM73-0 part with the address pin left floating. The sensor has other address options that you can try (like tying the address pin to Vdd or GND). Take a look at this latest setup of feedback and let me know if you are able to resolve the issue.