<?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>TWIM clock pin is pull low after sending zero bytes data.</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/37665/twim-clock-pin-is-pull-low-after-sending-zero-bytes-data</link><description>Dear Nordic 
 I found a example using nrfx_twim_rx() to scan slaves, I was just wondering if I can use nrfx_twim_tx() to scan slave devices by send zero byte data? I use nrfx_twim_tx() to send zero byte data to MCP23017 device, I don&amp;#39;t got error code</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 20 Aug 2018 10:10:06 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/37665/twim-clock-pin-is-pull-low-after-sending-zero-bytes-data" /><item><title>RE: TWIM clock pin is pull low after sending zero bytes data.</title><link>https://devzone.nordicsemi.com/thread/145079?ContentTypeID=1</link><pubDate>Mon, 20 Aug 2018 10:10:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:35d956fc-6105-429d-bdde-c3dd1f60ec24</guid><dc:creator>MartinBL</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Looks good. I tested your fix on my MPU9255 sensor too, and it seems to work as you intend.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TWIM clock pin is pull low after sending zero bytes data.</title><link>https://devzone.nordicsemi.com/thread/145078?ContentTypeID=1</link><pubDate>Thu, 16 Aug 2018 02:39:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dfe62e9a-46c3-4e07-a766-0f253ccd04dd</guid><dc:creator>yuting0501</dc:creator><description>&lt;p&gt;Hi Martin, thanks for your reply, the background is our user will use our i2c api to send zero byte to scan slave device. In Nordic SDK, if we send zero byte, it won&amp;#39;t generate any events, and STOP signal is shorted to LASTTX and LASTRX, so if we send zero byte,&amp;nbsp;LASTTX event will never be triggered, I add a work around in SDK, it works fine now, could you please help review it?&lt;/p&gt;
&lt;p&gt;I add these lines:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;if (start_task == NRF_TWIM_TASK_STARTTX &amp;amp;&amp;amp; p_xfer_desc-&amp;gt;primary_length==0)
{
nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;To:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;__STATIC_INLINE nrfx_err_t twim_xfer(twim_control_block_t        * p_cb,
                                     NRF_TWIM_Type               * p_twim,
                                     nrfx_twim_xfer_desc_t const * p_xfer_desc,
                                     uint32_t                      flags)
{
    nrfx_err_t err_code = NRFX_SUCCESS;
    nrf_twim_task_t  start_task = NRF_TWIM_TASK_STARTTX;
    nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED;

    if (!nrfx_is_in_ram(p_xfer_desc-&amp;gt;p_primary_buf))
    {
        err_code = NRFX_ERROR_INVALID_ADDR;
        NRFX_LOG_WARNING(&amp;quot;Function: %s, error code: %s.&amp;quot;,
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }
    /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */
    nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
    if (p_cb-&amp;gt;busy)
    {
        nrf_twim_int_enable(p_twim, p_cb-&amp;gt;int_mask);
        err_code = NRFX_ERROR_BUSY;
        NRFX_LOG_WARNING(&amp;quot;Function: %s, error code: %s.&amp;quot;,
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }
    else
    {
        p_cb-&amp;gt;busy = ((NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER &amp;amp; flags) ||
                      (NRFX_TWIM_FLAG_REPEATED_XFER &amp;amp; flags)) ? false: true;
    }

    p_cb-&amp;gt;xfer_desc = *p_xfer_desc;
    p_cb-&amp;gt;repeated = (flags &amp;amp; NRFX_TWIM_FLAG_REPEATED_XFER) ? true : false;
    nrf_twim_address_set(p_twim, p_xfer_desc-&amp;gt;address);

    nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
    nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);

    twim_list_enable_handle(p_twim, flags);
    switch (p_xfer_desc-&amp;gt;type)
    {
    case NRFX_TWIM_XFER_TXTX:
        NRFX_ASSERT(!(flags &amp;amp; NRFX_TWIM_FLAG_REPEATED_XFER));
        NRFX_ASSERT(!(flags &amp;amp; NRFX_TWIM_FLAG_HOLD_XFER));
        NRFX_ASSERT(!(flags &amp;amp; NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER));
        if (!nrfx_is_in_ram(p_xfer_desc-&amp;gt;p_secondary_buf))
        {
            err_code = NRFX_ERROR_INVALID_ADDR;
            NRFX_LOG_WARNING(&amp;quot;Function: %s, error code: %s.&amp;quot;,
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }
        nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc-&amp;gt;p_primary_buf, p_xfer_desc-&amp;gt;primary_length);
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
        while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
        {}
        NRFX_LOG_DEBUG(&amp;quot;TWIM: Event: %s.&amp;quot;, EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED));
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc-&amp;gt;p_secondary_buf, p_xfer_desc-&amp;gt;secondary_length);
        p_cb-&amp;gt;int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
        break;
    case NRFX_TWIM_XFER_TXRX:
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc-&amp;gt;p_primary_buf, p_xfer_desc-&amp;gt;primary_length);
        if (!nrfx_is_in_ram(p_xfer_desc-&amp;gt;p_secondary_buf))
        {
            err_code = NRFX_ERROR_INVALID_ADDR;
            NRFX_LOG_WARNING(&amp;quot;Function: %s, error code: %s.&amp;quot;,
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }
        nrf_twim_rx_buffer_set(p_twim, p_xfer_desc-&amp;gt;p_secondary_buf, p_xfer_desc-&amp;gt;secondary_length);
        nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK |
                                    NRF_TWIM_SHORT_LASTRX_STOP_MASK);
        p_cb-&amp;gt;int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
        break;
    case NRFX_TWIM_XFER_TX:
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc-&amp;gt;p_primary_buf, p_xfer_desc-&amp;gt;primary_length);
        if (NRFX_TWIM_FLAG_TX_NO_STOP &amp;amp; flags)
        {
            nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
            p_cb-&amp;gt;int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
            nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
            evt_to_wait = NRF_TWIM_EVENT_SUSPENDED;
        }
        else
        {
            nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
            p_cb-&amp;gt;int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
        }
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
        break;
    case NRFX_TWIM_XFER_RX:
        nrf_twim_rx_buffer_set(p_twim, p_xfer_desc-&amp;gt;p_primary_buf, p_xfer_desc-&amp;gt;primary_length);
        nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK);
        p_cb-&amp;gt;int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
        start_task = NRF_TWIM_TASK_STARTRX;
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
        break;
    default:
        err_code = NRFX_ERROR_INVALID_PARAM;
        break;
    }

    if (!(flags &amp;amp; NRFX_TWIM_FLAG_HOLD_XFER) &amp;amp;&amp;amp; (p_xfer_desc-&amp;gt;type != NRFX_TWIM_XFER_TXTX))
    {
        nrf_twim_task_trigger(p_twim, start_task);
    }

    if (start_task == NRF_TWIM_TASK_STARTTX &amp;amp;&amp;amp; p_xfer_desc-&amp;gt;primary_length == 0)
    {
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
    }

    if (p_cb-&amp;gt;handler)
    {
        if (flags &amp;amp; NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER)
        {
            p_cb-&amp;gt;int_mask = NRF_TWIM_INT_ERROR_MASK;
        }
        nrf_twim_int_enable(p_twim, p_cb-&amp;gt;int_mask);

#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
        if ((flags &amp;amp; NRFX_TWIM_FLAG_HOLD_XFER) &amp;amp;&amp;amp; ((p_xfer_desc-&amp;gt;type == NRFX_TWIM_XFER_TX) ||
                                                   (p_xfer_desc-&amp;gt;type == NRFX_TWIM_XFER_TXRX)))
        {
            p_cb-&amp;gt;flags = flags;
            twim_list_enable_handle(p_twim, 0);
            p_twim-&amp;gt;FREQUENCY = 0;
            nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
            nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
        }
#endif
    }
    else
    {
        while (!nrf_twim_event_check(p_twim, evt_to_wait))
        {
            if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
            {
                NRFX_LOG_DEBUG(&amp;quot;TWIM: Event: %s.&amp;quot;, EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
                nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
                nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
                nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
                evt_to_wait = NRF_TWIM_EVENT_STOPPED;
            }
        }

        uint32_t errorsrc =  nrf_twim_errorsrc_get_and_clear(p_twim);

        p_cb-&amp;gt;busy = false;

        if (errorsrc)
        {
            err_code = twi_process_error(errorsrc);
        }
    }
    return err_code;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Eugene&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: TWIM clock pin is pull low after sending zero bytes data.</title><link>https://devzone.nordicsemi.com/thread/145077?ContentTypeID=1</link><pubDate>Tue, 31 Jul 2018 09:13:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ddc5d74a-c6b6-4bca-8d21-ad4332e38048</guid><dc:creator>MartinBL</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I tested this with an nRF52 DK and an MPU 9255. With this system the slave seems to be holding the SCL line low if I use&amp;nbsp;nrfx_twim_tx(), but send 0 bytes. I&amp;#39;m guessing that the slave is pulling on SCL because it is waiting for a payload after the initial address byte. If I remove the&amp;nbsp;slave the SCL line goes high after every NACKed address byte that I transmit. Does it work okay of you use&amp;nbsp;nrfx_twim_rx(), or transmit at least one byte?&lt;/p&gt;
&lt;p&gt;Can you elaborate on why you need to do it this way?&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Martin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>