AnsweredAssumed Answered

I2C works on Teensy 4.0, but not on same chip's EVB. SCL is asymmetrical on NXP EVB!.

Question asked by Nathan DeBard on Oct 29, 2019
Latest reply on Nov 8, 2019 by Jing Pan

I can use the Teensy 4.0 (RT1062) to talk with my Si514 and it'll acknowledge (ACK) back. Furthermore, I can control it perfectly. However, NXP's RT1020 evaluation board (EVB) does not result in ACK when using the EVB's I2C drivers.

 

Successful ACK from the Si514 being driven by the Teensy 4.0. Slave address 0x55.

 

No ACK from the Si514 being driven by the EVB's included drivers. It looks identical except for no ACK and the SCL line is not high as long. In other words, the SCL's duty cycle is shorter. It's about 37%. It seems to *start later*, not end earlier. I assume we want 50% duty cycle like in the teensy 4.0. This may be the problem? If it is I have no idea how to change/fix it. Does anyone?

 

If you overlay the two pictures, it's obvious that the only difference is the SCL clock width while high (duty cycle), and of course the ACK bit difference on the end. Could the SCL duty cycle cause this problem? Does anyone know how to change this in the included EVB driver? I've been through a lot of settings in it but can't seem to find a way to modify the clock itself.

 

Why would NXP's driver put out an asymmetrical SCL???? That seems so strange!

 

There is this struct in the EVB driver, but none seem to affect SCL's duty cycle. I've played with various values of many of these to no avail.

 

typedef struct _lpi2c_master_config
{
bool enableMaster; /*!< Whether to enable master mode. */
bool enableDoze; /*!< Whether master is enabled in doze mode. */
bool debugEnable; /*!< Enable transfers to continue when halted in debug mode. */
bool ignoreAck; /*!< Whether to ignore ACK/NACK. */
lpi2c_master_pin_config_t pinConfig; /*!< The pin configuration option. */
uint32_t baudRate_Hz; /*!< Desired baud rate in Hertz. */
uint32_t busIdleTimeout_ns; /*!< Bus idle timeout in nanoseconds. Set to 0 to disable. */
uint32_t pinLowTimeout_ns; /*!< Pin low timeout in nanoseconds. Set to 0 to disable. */
uint8_t sdaGlitchFilterWidth_ns; /*!< Width in nanoseconds of glitch filter on SDA pin. Set to 0 to disable. */
uint8_t sclGlitchFilterWidth_ns; /*!< Width in nanoseconds of glitch filter on SCL pin. Set to 0 to disable. */
struct
{
bool enable; /*!< Enable host request. */
lpi2c_host_request_source_t source; /*!< Host request source. */
lpi2c_host_request_polarity_t polarity; /*!< Host request pin polarity. */
} hostRequest; /*!< Host request options. */
} lpi2c_master_config_t;

 

This struct and two other parameters are passed to a function to start the transfer by sending out the address (0x55 in this case).

 

My eyes were also drawn to these two functions that set up clocks, but I can't find any way to modify SCL's duty cycle inside them.

 

/*Clock setting for LPI2C*/
CLOCK_SetMux(kCLOCK_Lpi2cMux, LPI2C_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER);

Outcomes