<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/62370/i2c-example-with-latest-drivers</link><description>Hi, 
 I am using nRF52840 to communicate with the EEPROM. 24AA32AT-I/MC over I2C interface. The TWI scanner example detects the EEPROM address correctly for me .Now, I want to read/write the EEPROM. 
 As you know nrf and other drivers are deprecated in</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 19 Jun 2020 09:05:41 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/62370/i2c-example-with-latest-drivers" /><item><title>RE: I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/thread/255912?ContentTypeID=1</link><pubDate>Fri, 19 Jun 2020 09:05:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:065de499-0bc1-4932-a6d5-270ea22fcdc0</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
[quote user="Jagbir"]Thanks for the reply.[/quote]
&lt;p&gt;No problem at all, I am happy to help!&lt;/p&gt;
[quote user="Jagbir"]&amp;quot;From the looks of your code, I am not sure that your current&amp;nbsp;twim_evt_handler&amp;nbsp;is the best way to go..&amp;quot;[/quote][quote user="Jagbir"]This event handler attached&amp;nbsp;in my previous&amp;nbsp;post was from nrf_drv_twi.c. Does&amp;nbsp;the twim_evt_handler() really&amp;nbsp; handle any events? All it seems to do is copy data from one layer to another (nrf_drv_twi_xfer_type_t). Is that correct.[/quote]
&lt;p&gt;My mistake, I seem to have misinterpret your code.&lt;br /&gt;You are correct in your analysis of the default twim_evt_handler included in the nrf_drv_twi source code. However, if you look where/when this event handler is used, it is only in the case that you are using a combination of legacy and nrfx twi drivers. So, only in the case that you are using the nrfx_twim module together with the nrf_drv legacy module, then this function will come into play.&lt;br /&gt;The nrf_drv legacy drivers also had a feature for making module instances blocking by providing NULL as the event_handler argument to their _init() calls.&lt;br /&gt;This functionality is no longer supported in the nrfx - but it still &amp;#39;obfuscates&amp;#39; the nrf_drv source code, making it harder to read.&lt;br /&gt;&lt;br /&gt;In essence, if you are using the nrfx_twim driver only, then you do not need to worry about the nrf_drv source code. Furthermore, you should create a twim_evt_handler that you provide during your nrfx_twim_init call, and this function should handle &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v16.0.0%2Fgroup__nrfx__twim.html&amp;amp;anchor=gaa340de641ad707d1043fad3db17b7a76"&gt;the possible twim events&lt;/a&gt;.&lt;br /&gt;In this case, there is no point in including the twim_evt_handler from the nrf_drv_twi source code.&lt;br /&gt;Furthermore, I recommend that you primarily make use of the module functionality as described in the SDK Documentation and API Reference, rather than deducing their utility from the source code - such as in this case, the twim_evt_handler you reference from the nrf_drv_twi source code is not in the &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v16.0.0%2Fgroup__nrf__drv__twi.html"&gt;API Reference&lt;/a&gt;&amp;nbsp;as it is intended for internal use by the driver.&lt;br /&gt;The function itself has little to no utility in an application, as it is included only to maintain compatibility between the modules.&lt;/p&gt;
[quote user="Jagbir"]I have a similar question on clock driver nrf_drv_clock.c which is used by twim .I believe this driver is also legacy and should be replaced by nrfx_clock.c .[/quote]
&lt;p&gt;Yes, the nrf_drv_clock is also legacy&amp;nbsp;but unfortunately it is not as straight forward to migrate to nrfx_clock, due to the complexity of its complex dependencies.&lt;br /&gt;Please see the &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v17.0.0%2Fnrfx_migration_user_guide.html"&gt;nrfx migration documentation&lt;/a&gt; for further information about this.&lt;br /&gt;&lt;br /&gt;Please do not hesitate to ask if anything of this should still be unclear - the learning curve in this part of the SDK is sometimes quite steep.&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/thread/255812?ContentTypeID=1</link><pubDate>Thu, 18 Jun 2020 14:10:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2f454672-8855-459b-b0de-ea573cfd29f2</guid><dc:creator>Jagbir</dc:creator><description>&lt;p&gt;Hi Karl,&lt;/p&gt;
&lt;p&gt;Thanks for the reply.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;From the looks of your code, I am not sure that your current&amp;nbsp;twim_evt_handler&amp;nbsp;is the best way to go..&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This event handler attached&amp;nbsp;in my previous&amp;nbsp;post was from nrf_drv_twi.c. Does&amp;nbsp;the twim_evt_handler() really&amp;nbsp; handle any events? All it seems to do is copy data from one layer to another (nrf_drv_twi_xfer_type_t). Is that correct.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I have a similar question on clock driver nrf_drv_clock.c which is used by twim .I believe this driver is also legacy and should be replaced by nrfx_clock.c .&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thanks.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/thread/255674?ContentTypeID=1</link><pubDate>Thu, 18 Jun 2020 07:06:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3599c700-1c1a-4648-a5d3-d7b0837ebc71</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
[quote user="Jagbir"]I had to insert a delay between read and write after which the code is working fine now.[/quote]
&lt;p&gt;As a general practice I would not recommend adding NOP instructions (nrf_delay_* functions) to fulfill timing requirements - since this is wasted power and computing time. Instead, you could for example have a timer that must trigger before continuing the transfer.&lt;br /&gt;One of the reasons why NOP cycles is subpar, is that the number of cycles is constant, regardless of it being interrupted by the SoftDevice.&lt;br /&gt;Furthermore, if you use a timer, you may connect it to the TWIM peripheral by PPI, and have a transaction or a number of transactions happen without requiring CPU intervention.&lt;/p&gt;
[quote user="Jagbir"]Is it possible to&amp;nbsp;completely bypass&amp;nbsp;nrf_drv_twi.c/.h and use nrfx_twim.c/.h directly. Do I need to implement twim_evt_handler() in my code, if not using&amp;nbsp;nrf_drv_twi.c/.h.[/quote]
&lt;p&gt;Yes, you may use the TWIM module directly. To do this, you would want to make use of the &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v16.0.0/group__nrfx__twim.html"&gt;TWIM API Reference&lt;/a&gt;. As you can see in the&amp;nbsp;&lt;em&gt;nrfx_twim_init&lt;/em&gt; function you have to supply an event handler, unless you want the TWIM to be blocking. You can see &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsdk_nrf5_v16.0.0%2Fgroup__nrfx__twim.html&amp;amp;anchor=gaa340de641ad707d1043fad3db17b7a76"&gt;the possible events to handle in the API Reference&lt;/a&gt; as well.&lt;br /&gt;From the looks of your code, I am not sure that your current &lt;em&gt;twim_evt_handler&lt;/em&gt; is the best way to go about handling the different events, since it does not differentiate between the different possibilities.&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/thread/255630?ContentTypeID=1</link><pubDate>Wed, 17 Jun 2020 21:02:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0129cf65-6182-4fcc-ae5c-998fa2b74882</guid><dc:creator>Jagbir</dc:creator><description>&lt;p&gt;Karl,&lt;/p&gt;
&lt;p&gt;I had to insert a delay between read and write after which the code is working fine now.&lt;/p&gt;
&lt;p&gt;Moving forward, since TWI driver is deprecated so I am trying to switch to the TWIM driver. After looking through&amp;nbsp;&lt;span&gt;nrf_drv_twi.c/.h ,&lt;/span&gt; I am concerned&amp;nbsp;that nrf_drv_twi.c/.h code seems to handle both the TWI and TWIM requests through various if conditions. For example&amp;nbsp;&amp;nbsp;twim_evt_handler(),nrfx_twim_init() functions uses twim, see attached code of the&amp;nbsp;&lt;span&gt;nrf_drv_twi.c&lt;/span&gt; .&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Is it possible to&amp;nbsp;completely bypass&amp;nbsp;nrf_drv_twi.c/.h and use nrfx_twim.c/.h directly. Do I need to implement twim_evt_handler() in my code, if not using&amp;nbsp;nrf_drv_twi.c/.h.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/**
 * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA &amp;quot;AS IS&amp;quot; AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include &amp;quot;nrf_drv_twi.h&amp;quot;
#include &amp;lt;nrf_delay.h&amp;gt;
#include &amp;lt;hal/nrf_gpio.h&amp;gt;

#ifdef TWIM_PRESENT
#define INSTANCE_COUNT   TWIM_COUNT
#else
#define INSTANCE_COUNT   TWI_COUNT
#endif

#define SCL_PIN_INIT_CONF                                     \
    ( (GPIO_PIN_CNF_SENSE_Disabled &amp;lt;&amp;lt; GPIO_PIN_CNF_SENSE_Pos) \
    | (GPIO_PIN_CNF_DRIVE_S0D1     &amp;lt;&amp;lt; GPIO_PIN_CNF_DRIVE_Pos) \
    | (GPIO_PIN_CNF_PULL_Pullup    &amp;lt;&amp;lt; GPIO_PIN_CNF_PULL_Pos)  \
    | (GPIO_PIN_CNF_INPUT_Connect  &amp;lt;&amp;lt; GPIO_PIN_CNF_INPUT_Pos) \
    | (GPIO_PIN_CNF_DIR_Input      &amp;lt;&amp;lt; GPIO_PIN_CNF_DIR_Pos))

#define SDA_PIN_INIT_CONF        SCL_PIN_INIT_CONF

#define SDA_PIN_UNINIT_CONF                                     \
    ( (GPIO_PIN_CNF_SENSE_Disabled   &amp;lt;&amp;lt; GPIO_PIN_CNF_SENSE_Pos) \
    | (GPIO_PIN_CNF_DRIVE_H0H1       &amp;lt;&amp;lt; GPIO_PIN_CNF_DRIVE_Pos) \
    | (GPIO_PIN_CNF_PULL_Disabled    &amp;lt;&amp;lt; GPIO_PIN_CNF_PULL_Pos)  \
    | (GPIO_PIN_CNF_INPUT_Disconnect &amp;lt;&amp;lt; GPIO_PIN_CNF_INPUT_Pos) \
    | (GPIO_PIN_CNF_DIR_Input        &amp;lt;&amp;lt; GPIO_PIN_CNF_DIR_Pos))

#define SCL_PIN_UNINIT_CONF      SDA_PIN_UNINIT_CONF

#define SCL_PIN_INIT_CONF_CLR                                 \
    ( (GPIO_PIN_CNF_SENSE_Disabled &amp;lt;&amp;lt; GPIO_PIN_CNF_SENSE_Pos) \
    | (GPIO_PIN_CNF_DRIVE_S0D1     &amp;lt;&amp;lt; GPIO_PIN_CNF_DRIVE_Pos) \
    | (GPIO_PIN_CNF_PULL_Pullup    &amp;lt;&amp;lt; GPIO_PIN_CNF_PULL_Pos)  \
    | (GPIO_PIN_CNF_INPUT_Connect  &amp;lt;&amp;lt; GPIO_PIN_CNF_INPUT_Pos) \
    | (GPIO_PIN_CNF_DIR_Output     &amp;lt;&amp;lt; GPIO_PIN_CNF_DIR_Pos))

#define SDA_PIN_INIT_CONF_CLR    SCL_PIN_INIT_CONF_CLR

static nrf_drv_twi_evt_handler_t m_handlers[INSTANCE_COUNT];
static void *                    m_contexts[INSTANCE_COUNT];

static void twi_clear_bus(nrf_drv_twi_config_t const * p_config)
{
    NRF_GPIO-&amp;gt;PIN_CNF[p_config-&amp;gt;scl] = SCL_PIN_INIT_CONF;
    NRF_GPIO-&amp;gt;PIN_CNF[p_config-&amp;gt;sda] = SDA_PIN_INIT_CONF;

    nrf_gpio_pin_set(p_config-&amp;gt;scl);
    nrf_gpio_pin_set(p_config-&amp;gt;sda);

    NRF_GPIO-&amp;gt;PIN_CNF[p_config-&amp;gt;scl] = SCL_PIN_INIT_CONF_CLR;
    NRF_GPIO-&amp;gt;PIN_CNF[p_config-&amp;gt;sda] = SDA_PIN_INIT_CONF_CLR;

    nrf_delay_us(4);

    for (int i = 0; i &amp;lt; 9; i++)
    {
        if (nrf_gpio_pin_read(p_config-&amp;gt;sda))
        {
            if (i == 0)
            {
                return;
            }
            else
            {
                break;
            }
        }
        nrf_gpio_pin_clear(p_config-&amp;gt;scl);
        nrf_delay_us(4);
        nrf_gpio_pin_set(p_config-&amp;gt;scl);
        nrf_delay_us(4);
    }
    nrf_gpio_pin_clear(p_config-&amp;gt;sda);
    nrf_delay_us(4);
    nrf_gpio_pin_set(p_config-&amp;gt;sda);
}

#ifdef TWIM_PRESENT
static void twim_evt_handler(nrfx_twim_evt_t const * p_event,
                             void *                  p_context)
{
    uint32_t inst_idx = (uint32_t)p_context;
    nrf_drv_twi_evt_t const event =
    {
        .type = (nrf_drv_twi_evt_type_t)p_event-&amp;gt;type,
        .xfer_desc =
        {
            .type = (nrf_drv_twi_xfer_type_t)p_event-&amp;gt;xfer_desc.type,
            .address          = p_event-&amp;gt;xfer_desc.address,
            .primary_length   = p_event-&amp;gt;xfer_desc.primary_length,
            .secondary_length = p_event-&amp;gt;xfer_desc.secondary_length,
            .p_primary_buf    = p_event-&amp;gt;xfer_desc.p_primary_buf,
            .p_secondary_buf  = p_event-&amp;gt;xfer_desc.p_secondary_buf,
        }
    };
    m_handlers[inst_idx](&amp;amp;event, m_contexts[inst_idx]);
}
#endif // TWIM_PRESENT

#ifdef TWI_PRESENT
static void twi_evt_handler(nrfx_twi_evt_t const * p_event,
                            void *                 p_context)
{
    uint32_t inst_idx = (uint32_t)p_context;
    nrf_drv_twi_evt_t const event =
    {
        .type = (nrf_drv_twi_evt_type_t)p_event-&amp;gt;type,
        .xfer_desc =
        {
            .type = (nrf_drv_twi_xfer_type_t)p_event-&amp;gt;xfer_desc.type,
            .address          = p_event-&amp;gt;xfer_desc.address,
            .primary_length   = p_event-&amp;gt;xfer_desc.primary_length,
            .secondary_length = p_event-&amp;gt;xfer_desc.secondary_length,
            .p_primary_buf    = p_event-&amp;gt;xfer_desc.p_primary_buf,
            .p_secondary_buf  = p_event-&amp;gt;xfer_desc.p_secondary_buf,
        }
    };
    m_handlers[inst_idx](&amp;amp;event, m_contexts[inst_idx]);
}
#endif // TWI_PRESENT

ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const *        p_instance,
                            nrf_drv_twi_config_t const * p_config,
                            nrf_drv_twi_evt_handler_t    event_handler,
                            void *                       p_context)
{
    uint32_t inst_idx = p_instance-&amp;gt;inst_idx;
    m_handlers[inst_idx] = event_handler;
    m_contexts[inst_idx] = p_context;

    if(p_config-&amp;gt;clear_bus_init)
    {
        /* Send clocks (max 9) until slave device back from stuck mode */
        twi_clear_bus(p_config);
    }

    ret_code_t result = 0;
    if (NRF_DRV_TWI_USE_TWIM)
    {
        result = nrfx_twim_init(&amp;amp;p_instance-&amp;gt;u.twim,
                                (nrfx_twim_config_t const *)p_config,
                                event_handler ? twim_evt_handler : NULL,
                                (void *)inst_idx);
    }
    else if (NRF_DRV_TWI_USE_TWI)
    {
        result = nrfx_twi_init(&amp;amp;p_instance-&amp;gt;u.twi,
                               (nrfx_twi_config_t const *)p_config,
                               event_handler ? twi_evt_handler : NULL,
                               (void *)inst_idx);
    }
    return result;
}
&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;br /&gt;Thanks!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/thread/255023?ContentTypeID=1</link><pubDate>Mon, 15 Jun 2020 12:54:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:701ed8cd-0767-4802-b2fd-a67dec471241</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
[quote user="Jagbir"]D&lt;span&gt;uring debugging&amp;nbsp;and the the execution of write function,&lt;/span&gt;&amp;nbsp;I am getting a&amp;nbsp;&lt;b&gt;DRV_TWI_ERR_ANACK&lt;/b&gt;&lt;span&gt;&amp;nbsp;error&amp;nbsp;0x0000820.&lt;/span&gt;[/quote]
&lt;p&gt;The DRV_TWI_ERR_ANACK error code has value 8201, for future reference.&lt;br /&gt;From the looks of it, you are receiving an ACK with the SDA being low at the time of the ACK bit, so lets look into the error that is being generated.&lt;/p&gt;
[quote user="Jagbir"]&lt;span&gt;If I remove all the breakpoints from the code and let it run its full course then I get the following condition, which I can only&lt;/span&gt;&lt;span&gt;&amp;nbsp;get out only by&amp;nbsp;asserting the reset pin on nRF52.&lt;/span&gt;[/quote]
&lt;p&gt;When you do have the breakpoint, this is where you get the DRV_TWI_ERR_ANACK error?&lt;br /&gt;And if not, could you step through the code and see where the error is generated?&lt;br /&gt;Is your call to&amp;nbsp;nrf_drv_twi_rx successful?&lt;br /&gt;&lt;br /&gt;As I said, I would again recommend using the nrfx driver, since the nrf_drv* is legacy.&lt;br /&gt;The functionality of the &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v16.0.0/group__nrfx__twim.html"&gt;nrfx TWIM driver is detailed in the API Reference&lt;/a&gt;. Having said that, you can use whichever you would like - just know that the nrf_drv* calls might be left out of future SDK releases.&lt;br /&gt;&lt;br /&gt;Taking a look at the code you provided: why do you error check after declaring the err_code variable?&lt;br /&gt;You do not need to add NOP cycles to you main loop while you are using the WFI/WFE, but I would suggest using the power managing driver, for convenience.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Looking forward to solving this issue together,&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/thread/254808?ContentTypeID=1</link><pubDate>Fri, 12 Jun 2020 21:53:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ce6c4b43-c3b2-41ae-acd8-f46f217132f7</guid><dc:creator>Jagbir</dc:creator><description>&lt;p&gt;Karl,&lt;/p&gt;
&lt;p&gt;I am using sdk 16, SES ,nRf52840 the simulated EEPROM example&amp;nbsp;with an actual E&lt;span&gt;EPROM&amp;nbsp;(&lt;/span&gt;&lt;span&gt;24AA32AT-I/MC) connected&lt;/span&gt;&amp;nbsp;but I am not using any of the CLI/UART features of the example. Instead, I am trying to write direct TWI read and write functions, see attached code. In the write function, I am trying to write&amp;nbsp;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0xff)&lt;/span&gt; to the&amp;nbsp;&lt;span&gt;EEPROM located&amp;nbsp;&lt;span&gt;at&amp;nbsp;&lt;/span&gt;&lt;/span&gt;0x52 address. D&lt;span&gt;uring debugging&amp;nbsp;and the the execution of write function,&lt;/span&gt;&amp;nbsp;I am getting a&amp;nbsp;&lt;b&gt;DRV_TWI_ERR_ANACK&lt;/b&gt;&lt;span&gt;&amp;nbsp;error&amp;nbsp;0x0000820. I don&amp;#39;t understand why I am getting this NACK . As you can see in the attached scope picture, the data pin is low on 9th clock pulse, hence it should be a perceived&amp;nbsp;as ACK by the&amp;nbsp; nRF52. One interesting&amp;nbsp;fact is that by using&amp;nbsp;the same hardware settings, I am able to poll EEPROM address (0x52) while using the twi scanner example.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If I remove all the breakpoints from the code and let it run its full course then I get the following condition, which I can only&lt;/span&gt;&lt;span&gt;&amp;nbsp;get out only by&amp;nbsp;asserting the reset pin on nRF52.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;em&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NRF_BREAKPOINT_COND;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// On assert, the system can only recover with a reset&lt;/em&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/**
 * Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA &amp;quot;AS IS&amp;quot; AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/**
 * @file
 * @brief File with example code presenting usage of drivers for TWIS slave and TWI in master mode
 *
 * @sa twi_master_with_twis_slave_example
 */

/**
 * @defgroup twi_master_with_twis_slave_example Example code presenting usage of drivers for TWIS slave and TWI in master mode
 *
 * This code presents the usage of two drivers:
 * - @ref nrf_twi_drv (in synchronous mode)
 * - @ref nrf_twis_drv (in asynchronous mode)
 *
 * On the slave, EEPROM memory is simulated.
 * The size of the simulated EEPROM is configurable in the config.h file.
 * Default memory value of the device is 320 bytes. It is simulated using internal RAM.
 * This RAM area is accessed only by simulated EEPROM so the rest of the application can access it
 * only using TWI commands via hardware configured pins.
 *
 * The selected memory chip uses a 7-bit constant address. Word to access is selected during
 * a write operation: first byte sent is used as the current address pointer.
 *
 * A maximum of an 8-byte page can be written in a single access.
 * The whole memory can be read in a single access.
 *
 * When the slave (simulated EEPROM) is initialized, it copies the given part of flash
 * (see EEPROM_SIM_FLASH_ADDRESS in config.h) into RAM (enabling the use of the slave for
 * bootloader use cases).
 *
 * Many variables like length of sequential writes/reads, TWI instance to use, endianness of
 * of slave bype addressing can be configured in config.h file
 *
 * Differences between real chip and simulated one:
 * 1. Simulated chip has practically 0 ms write time.
 *    This example does not poll the memory for readiness.
 * 2. During sequential read, when memory end is reached, there is no support for roll-over.
 *    It is recommended for master to assure that it does not try to read more than the page limits.
 *    If the master is not tracking this and trying to read after the page ends, then the slave will start to NACK
 *    for trying to over-read the memory. The master should end the transaction when slave starts NACKing, which could
 *    mean that the master has read the end of the page.
 * 3. It is possible to write a maximum of EEPROM_SIM_SEQ_WRITE_MAX_BYTES bytes in a single
 *    sequential write. However, in simulated EEPROM the whole address pointer is incremented.
 *    In a real device, writing would roll-over in memory page.
 *
 * On the master side, we communicate with that memory and allow write and read.
 * Simple commands via UART can be used to check the memory.
 *
 * Pins to short:
 * - @ref TWI_SCL_M - @ref EEPROM_SIM_SCL_S
 * - @ref TWI_SDA_M - @ref EEPROM_SIM_SDA_S
 *
 * Supported commands will be listed after Tab button press.
 * @{
 */

#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;ctype.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;quot;config.h&amp;quot;
//#include &amp;quot;eeprom_simulator.h&amp;quot;
#include &amp;quot;nrf_drv_twi.h&amp;quot;
#include &amp;quot;nrf_gpio.h&amp;quot;
#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;bsp.h&amp;quot;
#include &amp;quot;app_util_platform.h&amp;quot;
#include &amp;quot;app_timer.h&amp;quot;
#include &amp;quot;nrf_drv_clock.h&amp;quot;
#include &amp;quot;nrf_delay.h&amp;quot;
#define EEPROM_ADD 0x52

//#include &amp;quot;nrf_log.h&amp;quot;
//#include &amp;quot;nrf_log_ctrl.h&amp;quot;
//#include &amp;quot;nrf_log_default_backends.h&amp;quot;

//#include &amp;quot;nrf_cli.h&amp;quot;
//#include &amp;quot;nrf_cli_uart.h&amp;quot;


//NRF_CLI_UART_DEF(m_cli_uart_transport, 0, 64, 16);
//NRF_CLI_DEF(m_cli_uart, &amp;quot;uart_cli:~$ &amp;quot;, &amp;amp;m_cli_uart_transport.transport, &amp;#39;\r&amp;#39;, 4);

/**
 * @brief TWI master instance.
 *
 * Instance of TWI master driver that will be used for communication with 
 * EEPROM memory.
 */
static const nrf_drv_twi_t m_twi_master = NRF_DRV_TWI_INSTANCE(MASTER_TWI_INST);

/**
 * @brief Initialize the master TWI.
 *
 * Function used to initialize the master TWI interface that would communicate with simulated EEPROM.
 *
 * @return NRF_SUCCESS or the reason of failure.
 */
static ret_code_t twi_master_init(void)
{
    ret_code_t ret;
    const nrf_drv_twi_config_t config =
    {
       .scl                = TWI_SCL_M,
       .sda                = TWI_SDA_M,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    ret = nrf_drv_twi_init(&amp;amp;m_twi_master, &amp;amp;config, NULL, NULL);

    if (NRF_SUCCESS == ret)
    {
        nrf_drv_twi_enable(&amp;amp;m_twi_master);
    }

    return ret;
}

/**
 *  The beginning of the journey
 */
int main(void)
{
    uint8_t clear_val = 0xFF;
    uint8_t addr = 0x00;
    ret_code_t err_code;
    uint8_t tx_buffer[EEPROM_ADDRESS_LEN_BYTES + EEPROM_SEQ_WRITE_MAX_BYTES]; 
    //Transmit buffer declaration
    uint8_t rx_data;
    //Transmit buffer declaration
    APP_ERROR_CHECK(err_code);
    /* Initializing TWI master interface for EEPROM */
    err_code = twi_master_init();
    APP_ERROR_CHECK(err_code);
     /* Initializing clock */
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
     /* Initializing low freqiency clock */
    nrf_drv_clock_lfclk_request(NULL);
     /* Initializing Timer */
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);
    
    memcpy(tx_buffer, &amp;amp;clear_val, EEPROM_SEQ_WRITE_MAX_BYTES); 
    //Load the Tx buffer with 0xFF

    err_code = nrf_drv_twi_tx(&amp;amp;m_twi_master, EEPROM_ADDR, tx_buffer, sizeof(tx_buffer), false);
    //Write buffer data to EEPROM
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_twi_rx(&amp;amp;m_twi_master, EEPROM_ADDR, &amp;amp;rx_data, 2);
    //Read from EEPROM
    APP_ERROR_CHECK(err_code);

   /* Main loop */
    while (1)
    {
    nrf_delay_ms(100);
    __WFI();
    }
 }
&lt;/pre&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/1040x0/__key/communityserver-discussions-components-files/4/Error0x00008201.jpg" /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1591998671575v2.png" /&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1591998772713v3.png" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: I2C example with latest drivers</title><link>https://devzone.nordicsemi.com/thread/254311?ContentTypeID=1</link><pubDate>Wed, 10 Jun 2020 15:12:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e46a0c55-a445-4b33-a294-620b8cbd91cc</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
[quote user=""]As you know nrf and other drivers are deprecated in the SDK 16 and its recommended to use nrfx/latest drivers. I just wanted&lt;span&gt;&amp;nbsp;&lt;/span&gt;to know that&lt;span&gt;&amp;nbsp;&lt;/span&gt;out of the 4 TWI/I2C examples in SDK 16, which is best suited for my application for further development and does not use the legacy drivers.&amp;nbsp;[/quote]
&lt;p&gt;This is correct, and to avoid having to port the application to the nrfx drivers in the future, I would highly recommend using the nrfx drivers from the start.&lt;br /&gt;&lt;br /&gt;I would suggest the&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v16.0.0/twi_master_with_twis_slave_example.html"&gt;TWIS Slave and TWI Master mode example from the SDK&lt;/a&gt;, since it demonstrates reading and writing to a (simulated) EEPROM module.&lt;br /&gt;If you look into the function being used for the master side, they do utilize the nrfx_twim driver - depending on the configuration.&lt;br /&gt;&lt;br /&gt;The learning curve for the TWI and TWIM/TWIS drivers is sometimes quite steep - please do not hesitate to ask if you encounter any issues or questions!&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>