0
\$\begingroup\$

I am trying to communicate with a cypress MCU (at 100kHz) that has been configured as I2C slave with adress 0x48. the document says the following. enter image description here

Now when I send this adress from my Sinowealth MCU, slave does not respond with ACK. here is the waveform enter image description here

When I tested same with arduino, it is responding with ACK and I am able to send data packet successfully. Here is the waveform when I using arduino as master and cypress MCU as slave. enter image description here

I do not have access to cypress MCU code or board schematics. I am using Open drain configration with internal push-up resistors on my board. Here is the schematics of my I2C side of board. enter image description here

What I have tried so far

  1. Lower clock till 10Khz, still no ACK
  2. Programmed arduino as slave with adress 0x48, it does not ack as well

What should I do? should I put external pull-ups or try some thing else? Untill now I have not tried external pull-upp as arduino board was also using internal pull ups and working fine.

PS:- Upon more inspection I find out there is an I2C EEPROM chip connected to same I2C pins as following. enter image description here

SO 2k2 external pull ups are already there. I tried disabling internal pull-ups as well but did not worked.

\$\endgroup\$
8
  • \$\begingroup\$ Try external pull-up resistors. Maybe 2k to 10k range, 4k7 could be a good start. If it works, I have an answer. \$\endgroup\$
    – Justme
    Commented Apr 26 at 11:12
  • \$\begingroup\$ Can you look at the waveforms with a scope instead of a logic probe? \$\endgroup\$ Commented Apr 26 at 11:35
  • \$\begingroup\$ @Justme I think that is the last resort \$\endgroup\$ Commented Apr 26 at 12:40
  • \$\begingroup\$ @ScottSeidman unfortunately I do not have oscilloscope with me right now \$\endgroup\$ Commented Apr 26 at 12:40
  • \$\begingroup\$ @Justme 4.7k pull up tried, but has not worked \$\endgroup\$ Commented Apr 26 at 13:31

1 Answer 1

0
\$\begingroup\$

The Issue has been resolved. The problem was in GPIO_Init() function in driver provided by Sinowealth. there was if statement on GPIO mode which was stoping it to configure SDA and SCL lines in OD mode. Here is the code snippet

void GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct){
uint32_t pinPos = 0x00, pos = 0x00, currentPin = 0x00;

/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));

/* Configure the port pins */
while ((GPIO_InitStruct->GPIO_Pin >> pinPos) != 0x00)
{
    pos = ((uint32_t)0x01) << pinPos;
    /* Get the port pins position */
    currentPin = (GPIO_InitStruct->GPIO_Pin) & pos;

    if (currentPin == pos)
    {
        GPIOx->MODER &= ~((uint16_t)GPIO_MODER_MODER0_Msk << (pinPos));
        GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << pinPos);

        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT)
        {
            /* Check the output driver parameters */
            assert_param(IS_GPIO_ODRV(GPIO_InitStruct->GPIO_ODrv));

            /*Output driver configuration */
            GPIOx(CFG)->ODRVR.V32 &= ~((uint32_t)GPIO_CFG_ODRVR_ODRVR0_Msk << (pinPos * 2));
            GPIOx(CFG)->ODRVR.V32 |= ((uint32_t)(GPIO_InitStruct->GPIO_ODrv) << (pinPos * 2));

            /* Output type parameter check */
            assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));

            /* Output type configuration */
            GPIOx(CFG)->OTYPER &= ~((uint16_t)GPIO_CFG_OTYPER_OT0_Msk << pinPos);
            GPIOx(CFG)->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << pinPos);
        }

        /* Pull-up Pull-down configuration   GPIO_CFG_PUPDR_PHDR0_Msk  */
        GPIOx(CFG)->PUPDR.V32 &= ~((uint32_t)GPIO_CFG_PUPDR_PHDR0_Msk << (pinPos * 2));
        GPIOx(CFG)->PUPDR.V32 &= ~((uint32_t)GPIO_CFG_PUPDR_PLDR0_Msk << (pinPos * 2));
        GPIOx(CFG)->PUPDR.V32 |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinPos * 2));
    }

    pinPos++;
}

}

Now I have changed this line to accomodate AF as well

     if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT || GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)

Now pin is being configured as OD and slave is able to ACK properly.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.