1 2 Previous Next 15 Replies Latest reply on Jan 15, 2015 6:24 PM by user_367297687

    I2C access with BCM943362WCD4

    initium

      Hi Wiced Engineers,

       

      Does the BCM943362WCD4 platform support I2C peripheral access.  I was not able to see initialization of platform_i2c_peripherals in the BCM943362WCD4 platform.c file.   Are there any examples of I2C access.

       

      Thanks

        • 1. Re: I2C access with BCM943362WCD4
          seyhan

          Hi,

           

          The wiced_i2c_init( wiced_i2c_device_t*) call in .../include/wiced_platform.h will initialize the I2C interface.

          The wiced_i2c_device_t is also defined in the header file.

          There are supporting functions  wiced_i2c_...(...) help you to send and receive data over I2C.

           

          You may fine help in .../Doc/API/group__i2c.html for functions.

           

          -Seyhan

          • 2. Re: I2C access with BCM943362WCD4
            initium

            Thanks for your response Seyhan.  I did notice the functions you pointed out but in the implementation of the function wiced_i2c_init() notice the following

             

            wiced_result_t wiced_i2c_init( wiced_i2c_device_t* device )

            {

            ...

                result = platform_i2c_init( &platform_i2c_peripherals[device->port], &config );

             

             

            The platform_i2c_peripherals variable is defined in platforms/BCM*/platform.c files and I was not able to see that for BCM943362WCD4.  Since STM's M3 itself supports I2C, I would imagine, it should be possible to do I2C, but as-is the SDK doesnot seem to have all the hooks in place for BCM943362WCD4.

             

            Are you saying that I2C access is working for you with the BCM943362WCD4?

             

            Regards,

            • 3. Re: I2C access with BCM943362WCD4
              seyhan

              Hi,

               

              Yes I2C is not included with BCM943362WCD4 platform files but it could be updated with I2C support. You may update the platform files similar to SPI or UART. Also you could check out other platform files where I2C is included in the platform files for sample.

               

              I will updated the BCM943362WCD4 platform files with I2C support and share.

               

              -Seyhan

              • 4. Re: I2C access with BCM943362WCD4
                initium

                Thanks for your response Seyhan.  It is good to know that it is workable.  It will be great if you can share the files, meanwhile I will try to look at the pin muxing and look at other platform files as well.

                 

                Best Regards

                • 5. Re: I2C access with BCM943362WCD4
                  jonathanday_1711826

                  Are there any known issues with wiced_result_t wiced_i2c_deinit( wiced_i2c_device_t* device )? It seems that when this is run then wiced_result_t wiced_i2c_init( wiced_i2c_device_t* device ) is run again, the I2C bus will not longer work. This is on our custom hardware but uses the API to perform the initialization.

                  • 6. Re: I2C access with BCM943362WCD4
                    phstream

                    I use wiced_i2c_deinit() then wiced_i2c_init() to recover from I2C failures. Reading errata for STM32F2 ARM processor they suggest a software reset on I2C to recover from I2C hanging in busy state.

                     

                    My recover code:

                    wiced_i2c_deinit(&device);

                     

                    /* I2C Software reset */

                    i2c_mapping[device.port].i2c->CR1 = 0x8000u;

                    wiced_rtos_delay_milliseconds(100 * MILLISECONDS);

                    i2c_mapping[device.port].i2c->CR1 = 0x0000u;


                    wiced_i2c_init(&device);


                    It works most of the time but sometimes I2C still hangs in busy state.


                    Any suggestions are welcome

                    //Peter

                    • 7. Re: I2C access with BCM943362WCD4
                      jonathanday_1711826

                      I did read up on the errata for i2C on the ST microprocessor too before I posted the inquiry. The I2C behavior after after wiced_i2c_deinit(); is called followed by wiced_i2c_init() becomes intermittent afterwards. I will try the the software reset as you suggested. I've looked at this for a while trying to understand what is happening. On my platform, I built a NoOS NoFS variant to test I2C directly and the issue appeared to go away. It seems that the issue is with the ThreadX implementation perhaps. I was able to reproduce some of the unusual behavior on the Eval Platform.

                       

                      I posted some more details up on Broadcom Support as some of this pertains to different hardware.

                      • 8. Re: I2C access with BCM943362WCD4
                        user_367297687

                        Did you solve your issue?  I would be very interested in some more details of your findings.  What did you use for settings for platform_i2c_peripherals (I am moving onto WICED 3.1.2 and the setup is different).  I am converting my working code over from WICED 2.4.1 where I used the following to reset:

                        wiced_result_t resetI2C(wiced_i2c_device_t *device)

                        {

                          wiced_result_t result = wiced_i2c_deinit(device);

                          if (WICED_SUCCESS != result)

                            WPRINT_APP_INFO(("I2C de-initialize failed with error:%d\r\n", result));

                          else

                          {

                            result = wiced_i2c_init(device);

                          }

                          return result;

                        }

                        • 9. Re: I2C access with BCM943362WCD4
                          jonathanday_1711826

                          Yes. It had to do with DMA (we had it enabled).

                           

                          Locate:

                           

                            platform_result_t platform_i2c_deinit( const platform_i2c_t* i2c, const platform_i2c_config_t* config )

                           

                          Comment out:

                           

                            RCC_AHB1PeriphClockCmd( i2c->tx_dma_peripheral_clock, DISABLE );

                           

                          This was disabling the UART so the system would hang. Bug still exists in SDK3.1.2.

                           

                          We are currently porting to 3.1.2 and have testing planned. Preliminary results look good so far.

                           

                          Bug exists in both WICED/platform/MCU/STM32F2xx, STM32F4xx

                          • 10. Re: I2C access with BCM943362WCD4
                            user_367297687

                            Thanks for the quick reply.  I'll give that a try!  Let's keep each other posted on the move to 3.1.2.  BTW, what did you use for platform_i2c_peripherals?  I have:

                             

                            const platform_i2c_t platform_i2c_peripherals[] =

                            {

                                    [WICED_I2C_1] =

                                    {

                                    .port                    = I2C1,

                                    .pin_scl                 = &platform_gpio_pins[WICED_GPIO_11],

                                    .pin_sda                 = &platform_gpio_pins[WICED_GPIO_12],

                                    .peripheral_clock_reg    = RCC_APB1Periph_I2C1,

                                    .tx_dma                  = DMA1,

                                    .tx_dma_peripheral_clock = RCC_AHB1Periph_DMA1,

                                    .tx_dma_stream           = DMA1_Stream7,

                                    .rx_dma_stream           = DMA1_Stream5,

                                    .tx_dma_stream_id        = 7,

                                    .rx_dma_stream_id        = 5,

                                    .tx_dma_channel          = DMA_Channel_1,

                                    .rx_dma_channel          = DMA_Channel_1,

                                    .gpio_af                 = GPIO_AF_I2C1

                                },

                            };

                            • 11. Re: I2C access with BCM943362WCD4
                              phstream

                              Hi!

                               

                              After a lot of experimenting I came up with a solution thats works for me.

                              If I get an error I try to reset the I2C module.

                              If that doesn't work I generate 9 clock cycles on the bus with GPIO and reset the I2C module.

                              That has solved every hickup so far.

                               

                              I don't use i2c_deinit() because it worked better without. Don't know why.

                              Reading SR causes some flags to reset. Don't remember which ones.

                               

                              Example I2C Read:

                               

                              result = wiced_i2c_init_rx_message(&message, buf, nbyte, 1 , WICED_TRUE);

                              if (result == WICED_SUCCESS) {

                                  result = wiced_i2c_transfer(&device, &message, 1);

                                  if (result != WICED_SUCCESS) {

                                      i2c_reset();

                                      result = wiced_i2c_transfer(&device, &message, 1);

                                      if (result != WICED_SUCCESS) {

                                          i2c_clock_recovery();

                                          result = wiced_i2c_transfer(&device, &message, 1);

                                          if (result != WICED_SUCCESS) i2c_reset();

                                      }

                                  }

                              }

                               

                              void i2c_reset() {

                                  log_info("I2C busy reset recovery sequence");

                               

                                  /* Log before status */

                                  logf_info("I2C SR1 = %04X, SR2 = %04X", i2c_mapping[device.port].i2c->SR1, i2c_mapping[device.port].i2c->SR2);

                               

                                  /* Reset I2C */

                                  i2c_mapping[device.port].i2c->CR1 = 0x8000u;

                                  wiced_rtos_delay_milliseconds(10 * MILLISECONDS);

                                  i2c_mapping[device.port].i2c->CR1 = 0x0000u;

                               

                                  /* Reinitialize I2C again */

                                  wiced_i2c_init(&device);

                               

                                  /* Log exit status */

                                  logf_info("I2C SR1 = %04X, SR2 = %04X", i2c_mapping[device.port].i2c->SR1, i2c_mapping[device.port].i2c->SR2);

                              }

                               

                              i2c_clock_recovery() {

                                  int i;

                               

                                  log_info("I2C busy clock recovery sequence");

                               

                                  /* Log before status */

                                  logf_info("I2C SR1 = %04X, SR2 = %04X", i2c_mapping[device.port].i2c->SR1, i2c_mapping[device.port].i2c->SR2);

                               

                                  /* Reset I2C */

                                  i2c_mapping[device.port].i2c->CR1 = 0x8000u;

                                  wiced_rtos_delay_milliseconds(10 * MILLISECONDS);

                                  i2c_mapping[device.port].i2c->CR1 = 0x0000u;

                               

                                  /* Set SCL & SDA as GPIO outputs */

                                  wiced_gpio_init (WICED_GPIO_18,  OUTPUT_OPEN_DRAIN_NO_PULL);

                                  wiced_gpio_init (WICED_GPIO_19,  OUTPUT_OPEN_DRAIN_NO_PULL);

                                  wiced_gpio_output_high(WICED_GPIO_18);

                                  wiced_gpio_output_high(WICED_GPIO_19);

                               

                                  /* Ripple clock to unhang external devices */

                                  for (i = 0; i < 9; i++) {

                                      wiced_gpio_output_low(WICED_GPIO_18);

                                      wiced_rtos_delay_milliseconds(1 * MILLISECONDS);

                                      wiced_gpio_output_high(WICED_GPIO_18);

                                      wiced_rtos_delay_milliseconds(1 * MILLISECONDS);

                                  }

                               

                                  /* Reinitialize I2C again */

                                  wiced_i2c_init(&device);

                               

                                  /* Log exit status */

                                  logf_info("I2C SR1 = %04X, SR2 = %04X", i2c_mapping[device.port].i2c->SR1, i2c_mapping[device.port].i2c->SR2);

                              }

                               

                              I don't know about platform_i2c_peripherals but used:

                               

                              const platform_i2c_mapping_t i2c_mapping[] =

                              {

                                  [WICED_I2C_1] =

                                  {

                                      .i2c = I2C1,

                                      .pin_scl                = &gpio_mapping[WICED_GPIO_18],

                                      .pin_sda                = &gpio_mapping[WICED_GPIO_19],

                                      .peripheral_clock_reg    = RCC_APB1Periph_I2C1,

                                      .tx_dma                  = DMA1,

                                      .tx_dma_peripheral_clock = RCC_AHB1Periph_DMA1,

                                      .tx_dma_stream          = DMA1_Stream7,

                                      .rx_dma_stream          = DMA1_Stream5,

                                      .tx_dma_stream_id        = 7,

                                      .rx_dma_stream_id        = 5,

                                      .tx_dma_channel          = DMA_Channel_1,

                                      .rx_dma_channel          = DMA_Channel_1,

                                      .gpio_af                = GPIO_AF_I2C1

                                  },

                              };

                              • 12. Re: I2C access with BCM943362WCD4
                                jonathanday_1711826

                                const platform_i2c_t platform_i2c_peripherals[] =

                                {

                                    [WICED_I2C_1] =

                                    {

                                        .port = I2C1,

                                        .pin_scl                 = &platform_gpio_pins[WICED_GPIO_17],

                                        .pin_sda                 = &platform_gpio_pins[WICED_GPIO_18],

                                        .peripheral_clock_reg    = RCC_APB1Periph_I2C1,

                                        .tx_dma                  = DMA1,

                                        .tx_dma_peripheral_clock = RCC_AHB1Periph_DMA1,

                                        .tx_dma_stream           = DMA1_Stream7,

                                        .rx_dma_stream           = DMA1_Stream0,

                                        .tx_dma_stream_id        = 7,

                                        .rx_dma_stream_id        = 0,

                                        .tx_dma_channel          = DMA_Channel_1,

                                        .rx_dma_channel          = DMA_Channel_1,

                                        .gpio_af                 = GPIO_AF_I2C1

                                    },

                                • 13. Re: I2C access with BCM943362WCD4
                                  user_367297687

                                  Thanks to the answers so far.  Very helpful.

                                  • 14. Re: I2C access with BCM943362WCD4
                                    seyhan

                                    Hi,

                                     

                                    This example may help you to communicate with I2C devices using WICED APIs, I2C Interface Example with WICED SDK-3.x

                                     

                                    Seyhan

                                    1 2 Previous Next