ESP8266 : I2c communications trouble

Clancys
Posts: 2
Joined: Tue Jun 26, 2018 9:52 pm

ESP8266 : I2c communications trouble

Postby Clancys » Tue Jul 10, 2018 5:19 pm

Hello,

I encountered some problems while using the I2c protocols on the ESP8266.
I am using the basic pins (GPIO2 for SDA and GPIO14 for SCL) and only the C language.
I am trying to exchange with a gps module (Sam-M8q) that can only be slave.
https://www.u-blox.com/sites/default/files/SAM-M8Q_DataSheet_%28UBX-16012619%29.pdf
The communication is working fine when i am using a Raspberry 3 as master.

The main trouble that I have is with the I2c clock (data got with the saleae logic software):

- 1st image : A read task is asked and the Esp8266 is not starting the clock to start the communication as it should be, so the exchange didn't work and i get bad data (0x00 is not a valid character is a NMEA frame)
- 2nd image : Not enough clock segment are sent (only 7 compared to the requested 9)

I know that the slave can stretch the clock to let him the time to compute and send the data but he can't initiate the clock sequence, only the master can do it.

The Esp as well as the Gps are set on breadboards, joined with standard cable and a constant 3.3V power source.

Here is the following code that i am using:
--> HalI2cWrite and HalI2cRead are basic functions using the Esp I2c_master.h functions, they are sending the setup address to read/write and then they send or receive the data only one byte at a time.
--> I am not sending a positioning order each time I want to read as the Gps documentation certifies that multiple read will always read in this position once it has been set once

Code: Select all

uint16 HalSamM8qGetFrame(uint8 *gnrmcFrame_tu8, uint8 maxFrameLength_u8)
{
    uint8 highBytes_u8;
    uint8 lowBytes_u8;
    uint16 frameLength_u16 = 0u;
    uint16 counter_u16 = 0u;
    uint8 i2cBuffer_tu8[GPSRECEIVER_MAXFRAMESIZE] = {0u};
   
    i2cBuffer_tu8[0] = 0xFDu;                            /* The address 0xFD is containing the higher byte of the frame length */
   
    HalI2cWrite(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);  /* Setting the pointer to the address */
    os_delay_us(500u);
    HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);   /* Reading register 0xFD */

    highBytes_u8 = i2cBuffer_tu8[0];
   
    i2cBuffer_tu8[0] = 0xFEu;                            /* The address 0xFE is containing the lower byte of the frame length */
   
    HalI2cWrite(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);  /* Setting the pointer to the address */
    os_delay_us(500u);
    HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);   /* Reading register 0xFE */
   
    lowBytes_u8 = i2cBuffer_tu8[0];
   
    frameLength_u16 = (uint16)((highBytes_u8 << 8u) + lowBytes_u8);

    if(frameLength_u16 != 0xFFFFu)
    {
        i2cBuffer_tu8[0] = 0xFFu;
        HalI2cWrite(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);  /* Setting the pointer to the address */
        os_delay_us(500u);
        HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);   /* Reading register 0xFF and so on, to see the frame */
       
        while((i2cBuffer_tu8[0] != '$') && (counter_u16 < frameLength_u16))  /* We have to read all the buffer to try to find the '$' */
        {
            HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);
           
            counter_u16++;
        }
       
        if(counter_u16 < frameLength_u16)   /* We don't want to read anything more if we haven't found the '$' in frameLength_u16 tries */
        {
            counter_u16 = 0u;
            gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0];
           
            while((i2cBuffer_tu8[0] != '*') && (counter_u16 < (maxFrameLength_u8 - 2u))) /* Reading and saving all the bytes until we found the "*" */
            {
                counter_u16++;
                HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);

                gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0u];
                system_soft_wdt_feed();
            }
           
            HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);       /* First byte of the checksum */
           
            counter_u16++;
            gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0u];

            counter_u16++;
            HalI2cRead(GPSRECEIVER_I2C_ADDR, i2cBuffer_tu8, 1u);       /* Second byte of the checksum */
            gnrmcFrame_tu8[counter_u16] = i2cBuffer_tu8[0u];
           
            counter_u16++;
        }
        else
        {
            counter_u16 = GPSRECEIVER_MAXFRAMESIZE;                    /* Setting the length of the frame to its max frame
                                                                          otherwise we have counter_u16 = frameLength_u16 */
        }
    }
    else
    {
        counter_u16 = GPSRECEIVER_MAXFRAMESIZE;                    /* Setting the length of the frame to its max frame
                                                                      otherwise we have counter_u16 = 0u */
    }
   
    return counter_u16;
}


Is it something i can do to make the Esp 100% viable on this point or
Have i done something wrong during all this time?

Thank you,
Clancys.
Attachments
Weird_Clock_Interaction2.PNG
Weird_Clock_Interaction1.PNG

Xiong Yu
Posts: 3
Joined: Tue Jul 17, 2018 11:17 am

Re: ESP8266 : I2c communications trouble

Postby Xiong Yu » Mon Aug 27, 2018 12:06 pm

I suggest you exchange SCL, SDA pins. Or set SCL to push pull mode.

Who is online

Users browsing this forum: Burtonbuh and 4 guests