<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Kinetis Microcontrollers中的主题 Re: i2c freertos</title>
    <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1410260#M62369</link>
    <description>&lt;P&gt;Dear&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/58763"&gt;@myke_predko&lt;/a&gt;&amp;nbsp;,&lt;/P&gt;&lt;P&gt;I'm also trying to bring &lt;STRONG&gt;&lt;EM&gt;fsl_i2c_freertos.c&lt;/EM&gt;&lt;/STRONG&gt;&amp;nbsp; from SDK to good use. But I'm worried that it does not properly lock i2c transactions.&lt;/P&gt;&lt;P&gt;I don't know the SDK code for your MCU, mine is for the LPC55xx and the relevant part looks like:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;status_t I2C_RTOS_Transfer(i2c_rtos_handle_t *handle, i2c_master_transfer_t *transfer)
{
    status_t status;
    /* Lock resource mutex */
    if (xSemaphoreTake(handle-&amp;gt;mutex, portMAX_DELAY) != pdTRUE)
    {
        return kStatus_I2C_Busy;
    }

    status = I2C_MasterTransferNonBlocking(handle-&amp;gt;base, &amp;amp;handle-&amp;gt;drv_handle, transfer);
    if (status != kStatus_Success)
    {
        (void)xSemaphoreGive(handle-&amp;gt;mutex);
        return status;
    }

    /* Wait for transfer to finish */
    (void)xSemaphoreTake(handle-&amp;gt;semaphore, portMAX_DELAY);

    /* Unlock resource mutex */
    (void)xSemaphoreGive(handle-&amp;gt;mutex);

    /* Return status captured by callback function */
    return handle-&amp;gt;async_status;
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The call to&amp;nbsp;I2C_MasterTransferNonBlocking() is protected by a mutex, however, the SDK is poorly written (in comparison to LPCOpen) and thus a single I2C transaction likely will have to use multiple calls to I2C_RTOS_Transfer(). In between these calls the I2C bus is left in a&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;busy state.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Consider two tasks accessing I2C via I2C_RTOS_Transfer(). The first task calls to send a write-datagram and omits the Stop-Condition ( to continue with the I2C-transaction with a call to a read data). What happens if a second task now accesses I2C_RTOS_Transfer? The I2C bus is still busy because the bus devices have seen a Start Condition but not yet a Stop Condition. But as the&amp;nbsp;I2C_RTOS_Transfer() is I2C-transaction-agnostic, it does not prevent this.&lt;/P&gt;&lt;P&gt;I assume one needs to add a I2C-transaction based lock.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Does that make sense?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Tue, 08 Feb 2022 12:14:12 GMT</pubDate>
    <dc:creator>danielholala</dc:creator>
    <dc:date>2022-02-08T12:14:12Z</dc:date>
    <item>
      <title>i2c freertos</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1274611#M60494</link>
      <description>&lt;P&gt;Hi, I need help.&lt;BR /&gt;And recently I have been working with freertos, I have been able to use different peripherals but I still have problems with I2C.&lt;/P&gt;&lt;P&gt;The examples are also very poor.&lt;BR /&gt;How can I read and write an I2C peripheral as I did with mqx 4.1.&lt;/P&gt;&lt;P&gt;Thanks to those who will help me.&lt;BR /&gt;a good example is welcome.&lt;/P&gt;&lt;P&gt;Maurizio&lt;/P&gt;</description>
      <pubDate>Mon, 10 May 2021 18:47:54 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1274611#M60494</guid>
      <dc:creator>Microfelix</dc:creator>
      <dc:date>2021-05-10T18:47:54Z</dc:date>
    </item>
    <item>
      <title>Re: i2c freertos</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1274752#M60497</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/3220"&gt;@Microfelix&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm guessing you're asking about master mode.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've attached my I2C write task written for FreeRTOS here.&amp;nbsp; In the task, a message with data to send is sent to the task which sends it out using I2C and returns when the transfer is complete (or has failed).&amp;nbsp; In the attached task I'm using the Kinetis FreeRTOS driver (&lt;A href="https://mcuxpresso.nxp.com/api_doc/dev/1863/group__i2c__freertos__driver.html" target="_blank" rel="noopener"&gt;I2C FreeRTOS Driver Reference&lt;/A&gt;) and you can see that it's really quite simple.&amp;nbsp; This code is for doing writes to an OLED display driver - another task loads "rxMsg" with the device address, provides a single dimensional array of UINT8_t bytes to transmit with the number of bytes specified.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Based on my experience with the ADC, SPI and UART FreeRTOS Kinetis drivers, I am going to rewrite this task to use the standard SDK I2C drivers with interrupts (where appropriate).&amp;nbsp; There should be less overhead along with having more control over the I2C port's operation.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regardless of what I want to do, the Kinetis I2C FreeRTOS drivers are very easy to work with&amp;nbsp; and can be used for fast/quick and dirty interfaces.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Good luck!&lt;/P&gt;&lt;P&gt;myke&lt;/P&gt;</description>
      <pubDate>Tue, 11 May 2021 03:54:42 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1274752#M60497</guid>
      <dc:creator>myke_predko</dc:creator>
      <dc:date>2021-05-11T03:54:42Z</dc:date>
    </item>
    <item>
      <title>Re: i2c freertos</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1275164#M60500</link>
      <description>&lt;P&gt;hi&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/58763"&gt;@myke_predko&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for the reply.&lt;BR /&gt;I've already tried, but the answer is always the same.&lt;BR /&gt;From my device, I see with oscilloscope only the first byte then nothing.&lt;BR /&gt;And I2C_RTOS_Transfer returns 0x451.&lt;BR /&gt;Some idea?&lt;/P&gt;&lt;P&gt;Maurizio&lt;/P&gt;</description>
      <pubDate>Tue, 11 May 2021 19:22:15 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1275164#M60500</guid>
      <dc:creator>Microfelix</dc:creator>
      <dc:date>2021-05-11T19:22:15Z</dc:date>
    </item>
    <item>
      <title>Re: i2c freertos</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1275175#M60501</link>
      <description>&lt;P&gt;HI&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/3220"&gt;@Microfelix&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;When you get error codes, you're going to have to do some digging in the source code and look at data in different formats - the documentation isn't great but looking at the source code it really isn't that hard and just takes a few seconds.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I clicked on "I2C_RTOS_Transfer" and then presed "F3" to go to "fsl_i2c_freertos.c" and in there, I saw that there is a "return kStatus_I2C_Busy;" statement at the start.&amp;nbsp; The value of the error is 1100 decimal.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I clicked on "kStatus_I2C_Busy" and then pressed "F3" and ended up in "fsl_i2c.h" with the code block:&lt;/P&gt;&lt;PRE&gt;enum _i2c_status&lt;BR /&gt;{&lt;BR /&gt;kStatus_I2C_Busy = MAKE_STATUS(kStatusGroup_I2C, 0), /*!&amp;lt; I2C is busy with current transfer. */&lt;BR /&gt;kStatus_I2C_Idle = MAKE_STATUS(kStatusGroup_I2C, 1), /*!&amp;lt; Bus is Idle. */&lt;BR /&gt;kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_I2C, 2), /*!&amp;lt; NAK received during transfer. */&lt;BR /&gt;kStatus_I2C_ArbitrationLost = MAKE_STATUS(kStatusGroup_I2C, 3), /*!&amp;lt; Arbitration lost during transfer. */&lt;BR /&gt;kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!&amp;lt; Timeout poling status flags. */&lt;BR /&gt;kStatus_I2C_Addr_Nak = MAKE_STATUS(kStatusGroup_I2C, 5), /*!&amp;lt; NAK received during the address probe. */&lt;BR /&gt;};&lt;/PRE&gt;&lt;P&gt;When I look at the "MAKE_STATUS" macro, it's multiplying the first parameter by 100 decimal and adding the second one to it.&amp;nbsp; If you hover over "kStatusGroup_I2C" you'll discover that it is equal to 11 decimal - for "kStatus_I2C_Busy" it's 11 * 100 plus 0 (as you can see above).&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now, 0x451 is 1105 decimal, so looking at the enum above, I can see that the message being returned is "kStatus_I2C_Addr_Nak" - you'll have to look at the address of the peripheral you're trying to address.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;On the address Nak error, here's a hint, you may have to take the I2C address specified in the peripheral chip's dtasheet and shift it to the left once (or multiply be 2, it's the same thing).&amp;nbsp; This is something of a quirk with these parts - the address is effectively shifted up by 2 when it is transmitted but this isn't done in the drivers.&amp;nbsp; I think everybody using I2C has been caught by this error.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regardless, I've spent about 10x the time writing up what I did compared to how much time it took to actually find the error's definition.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Good luck.&amp;nbsp;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 11 May 2021 20:04:05 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1275175#M60501</guid>
      <dc:creator>myke_predko</dc:creator>
      <dc:date>2021-05-11T20:04:05Z</dc:date>
    </item>
    <item>
      <title>Re: i2c freertos</title>
      <link>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1410260#M62369</link>
      <description>&lt;P&gt;Dear&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/58763"&gt;@myke_predko&lt;/a&gt;&amp;nbsp;,&lt;/P&gt;&lt;P&gt;I'm also trying to bring &lt;STRONG&gt;&lt;EM&gt;fsl_i2c_freertos.c&lt;/EM&gt;&lt;/STRONG&gt;&amp;nbsp; from SDK to good use. But I'm worried that it does not properly lock i2c transactions.&lt;/P&gt;&lt;P&gt;I don't know the SDK code for your MCU, mine is for the LPC55xx and the relevant part looks like:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;status_t I2C_RTOS_Transfer(i2c_rtos_handle_t *handle, i2c_master_transfer_t *transfer)
{
    status_t status;
    /* Lock resource mutex */
    if (xSemaphoreTake(handle-&amp;gt;mutex, portMAX_DELAY) != pdTRUE)
    {
        return kStatus_I2C_Busy;
    }

    status = I2C_MasterTransferNonBlocking(handle-&amp;gt;base, &amp;amp;handle-&amp;gt;drv_handle, transfer);
    if (status != kStatus_Success)
    {
        (void)xSemaphoreGive(handle-&amp;gt;mutex);
        return status;
    }

    /* Wait for transfer to finish */
    (void)xSemaphoreTake(handle-&amp;gt;semaphore, portMAX_DELAY);

    /* Unlock resource mutex */
    (void)xSemaphoreGive(handle-&amp;gt;mutex);

    /* Return status captured by callback function */
    return handle-&amp;gt;async_status;
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The call to&amp;nbsp;I2C_MasterTransferNonBlocking() is protected by a mutex, however, the SDK is poorly written (in comparison to LPCOpen) and thus a single I2C transaction likely will have to use multiple calls to I2C_RTOS_Transfer(). In between these calls the I2C bus is left in a&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;busy state.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Consider two tasks accessing I2C via I2C_RTOS_Transfer(). The first task calls to send a write-datagram and omits the Stop-Condition ( to continue with the I2C-transaction with a call to a read data). What happens if a second task now accesses I2C_RTOS_Transfer? The I2C bus is still busy because the bus devices have seen a Start Condition but not yet a Stop Condition. But as the&amp;nbsp;I2C_RTOS_Transfer() is I2C-transaction-agnostic, it does not prevent this.&lt;/P&gt;&lt;P&gt;I assume one needs to add a I2C-transaction based lock.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Does that make sense?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 08 Feb 2022 12:14:12 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Kinetis-Microcontrollers/i2c-freertos/m-p/1410260#M62369</guid>
      <dc:creator>danielholala</dc:creator>
      <dc:date>2022-02-08T12:14:12Z</dc:date>
    </item>
  </channel>
</rss>

