<?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>topic SD interface driver sets incorrect SD clock in LPC Microcontrollers</title>
    <link>https://community.nxp.com/t5/LPC-Microcontrollers/SD-interface-driver-sets-incorrect-SD-clock/m-p/805978#M32361</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I was looking at the SD bus signals on a scope and I noticed the clock speeds were all WAY off the mark.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Set 400 KHz, get ~118 KHz.&amp;nbsp; Cards don't work. (Must be why the high level driver enumerates at 20MHz)&lt;/LI&gt;&lt;LI&gt;Set 20 MHz, get 16.67 MHz. Usually works but it's slower than it should be.&lt;/LI&gt;&lt;LI&gt;Set 50 MHz, get 33.33 MHz. Usually not tolerated.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This looks suspiciously like a divisor being stepped up one notch further than it's supposed to be.&amp;nbsp; When I went through the SDIF driver I found the culprit was exactly that.&amp;nbsp; Look at the function Chip_SDIF_SetClock(). This is how it computes the divisor:&lt;/P&gt;&lt;PRE style="padding-left: 30px;"&gt;div = ((clk_rate / speed) + 2) &amp;gt;&amp;gt; 1;&lt;/PRE&gt;&lt;P&gt;This is wrong.&amp;nbsp; It should be &lt;STRONG&gt;+ 1&lt;/STRONG&gt;.&amp;nbsp; Once corrected I get the expected clocks and everything works perfectly.&amp;nbsp; All cards enumerate, high speed mode works, etc.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This makes your SD controller look much worse than it actually is!&amp;nbsp; When properly configured I can run any SD card I own in high-speed mode and get the full 25 MB/sec the controller is capable of - from ancient SD to SDHC to a brand new SDXC card. The SD controller is really a great piece of work. But I can't say the same for the drivers. :smileysilly:&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 27 Sep 2018 22:33:54 GMT</pubDate>
    <dc:creator>leecoakley</dc:creator>
    <dc:date>2018-09-27T22:33:54Z</dc:date>
    <item>
      <title>SD interface driver sets incorrect SD clock</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/SD-interface-driver-sets-incorrect-SD-clock/m-p/805978#M32361</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I was looking at the SD bus signals on a scope and I noticed the clock speeds were all WAY off the mark.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Set 400 KHz, get ~118 KHz.&amp;nbsp; Cards don't work. (Must be why the high level driver enumerates at 20MHz)&lt;/LI&gt;&lt;LI&gt;Set 20 MHz, get 16.67 MHz. Usually works but it's slower than it should be.&lt;/LI&gt;&lt;LI&gt;Set 50 MHz, get 33.33 MHz. Usually not tolerated.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This looks suspiciously like a divisor being stepped up one notch further than it's supposed to be.&amp;nbsp; When I went through the SDIF driver I found the culprit was exactly that.&amp;nbsp; Look at the function Chip_SDIF_SetClock(). This is how it computes the divisor:&lt;/P&gt;&lt;PRE style="padding-left: 30px;"&gt;div = ((clk_rate / speed) + 2) &amp;gt;&amp;gt; 1;&lt;/PRE&gt;&lt;P&gt;This is wrong.&amp;nbsp; It should be &lt;STRONG&gt;+ 1&lt;/STRONG&gt;.&amp;nbsp; Once corrected I get the expected clocks and everything works perfectly.&amp;nbsp; All cards enumerate, high speed mode works, etc.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This makes your SD controller look much worse than it actually is!&amp;nbsp; When properly configured I can run any SD card I own in high-speed mode and get the full 25 MB/sec the controller is capable of - from ancient SD to SDHC to a brand new SDXC card. The SD controller is really a great piece of work. But I can't say the same for the drivers. :smileysilly:&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 27 Sep 2018 22:33:54 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/SD-interface-driver-sets-incorrect-SD-clock/m-p/805978#M32361</guid>
      <dc:creator>leecoakley</dc:creator>
      <dc:date>2018-09-27T22:33:54Z</dc:date>
    </item>
    <item>
      <title>Re: SD interface driver sets incorrect SD clock</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/SD-interface-driver-sets-incorrect-SD-clock/m-p/805979#M32362</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Lee Coakley,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thanks a lot for your information sharing.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Do you also check the clk_rate, whether it is correct on your side.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; Because, if refer to the user manual:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper" image-alt="pastedImage_1.png"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/74363iE7742E6BDC94FE0E/image-size/large?v=v2&amp;amp;px=999" role="button" title="pastedImage_1.png" alt="pastedImage_1.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;div = ((clk_rate / speed) + 2) &amp;gt;&amp;gt; 1; is correct.&lt;/P&gt;&lt;P&gt;clk_rate/speed= (div*2-2)=(div-1)*2&lt;/P&gt;&lt;P&gt;So, I think we also need to check clk_rate, whether it is correct or not.&lt;/P&gt;&lt;P&gt;Can you help to check these point?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set 400 KHz, get ~118 KHz.&amp;nbsp; Cards don't work. (Must be why the high level driver enumerates at 20MHz)&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Set 20 MHz, get 16.67 MHz. Usually works but it's slower than it should be.&lt;/LI&gt;&lt;LI&gt;Set 50 MHz, get 33.33 MHz. Usually not tolerated.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Give me the above 3 situations pSDMMC-&amp;gt;CLKDIV data with div = ((clk_rate / speed) + 2) &amp;gt;&amp;gt; 1; and div = ((clk_rate / speed) + 1) &amp;gt;&amp;gt; 1;&lt;/P&gt;&lt;P&gt;Please also give me the code about calling Chip_SDIF_SetClock(LPC_SDMMC_T *pSDMMC, uint32_t clk_rate, uint32_t speed), especially clk_rate and speed data.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;Have a great day,&lt;BR /&gt;Kerry&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;-----------------------------------------------------------------------------------------------------------------------&lt;BR /&gt;Note: If this post answers your question, please click the Correct Answer button. Thank you!&lt;BR /&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 29 Sep 2018 08:29:47 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/SD-interface-driver-sets-incorrect-SD-clock/m-p/805979#M32362</guid>
      <dc:creator>kerryzhou</dc:creator>
      <dc:date>2018-09-29T08:29:47Z</dc:date>
    </item>
    <item>
      <title>Re: SD interface driver sets incorrect SD clock</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/SD-interface-driver-sets-incorrect-SD-clock/m-p/805980#M32363</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Kerry, I gathered the info.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The clock is enabled in Chip_SDIF_Init():&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Chip_Clock_EnableOpts(CLK_MX_SDIO, true, true, 1);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Clk_rate is read using this function, which returns 204 MHz:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Chip_Clock_GetBaseClocktHz(CLK_BASE_SDIO)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Used in this context:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Chip_SDIF_SetClock(pSDMMC, Chip_Clock_GetBaseClocktHz(CLK_BASE_SDIO), g_card_info-&amp;gt;card_info.speed);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I verified that the speed parameter makes sense. Console output:&lt;/P&gt;&lt;PRE style="padding-left: 30px;"&gt;speed = 400000
speed = 25000000
speed = 50000000&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;With the original computation where I observe the wrong frequency, the divisors are computed as:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;400 KHz: div = 256&lt;/LI&gt;&lt;LI&gt;20 MHz: div = 6&lt;/LI&gt;&lt;LI&gt;25 MHz: div = 5&lt;/LI&gt;&lt;LI&gt;50 MHz: div = 3&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;With my change it's one less:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;400 KHz: div = 255&lt;/LI&gt;&lt;LI&gt;20 MHz: div = 5&lt;/LI&gt;&lt;LI&gt;25 MHz: div = 4&lt;/LI&gt;&lt;LI&gt;50 MHz: div = 2&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Also confirmed on the scope that these frequencies are the ones being output.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Plugging in the formula from the reference manual it looks like my formula gives the better answer:&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;Original:&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 256) =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 398,438 (can't actually be set, 256 doesn't fit in the register so it was really 204MHz I guess)&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 6)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 17,000,000 (15% error)&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 5) &amp;nbsp; &amp;nbsp; = 20,400,000 (18% error)&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 3)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 34,000,000 (32% error)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;Revised:&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 255) =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 400,000 (0% error)&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 5)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 20,040,000 (2% error)&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 4) &amp;nbsp; &amp;nbsp; = 25,500,000 (2% error)&lt;/P&gt;&lt;P style="padding-left: 30px;"&gt;204,000,000 / (2 * 2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 51,000,000 (2% error)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Adding + 1 picks the nearest divisor resulting in the best match, adding + 2 rounds up the divisor which overshoots the division rate in all cases other than exact multiples.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Here's a plot in 100KHz increments with blue as the target and red as the actual output:&lt;/P&gt;&lt;P&gt;&lt;SPAN class="lia-inline-image-display-wrapper" image-alt="divisor plot.png"&gt;&lt;IMG alt="divisor plot.png" src="https://community.nxp.com/t5/image/serverpage/image-id/73641i6B317762228DEEEC/image-size/large?v=v2&amp;amp;px=999" title="divisor plot.png" /&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Swept over the range, the average error is halved in the revised version.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 02 Nov 2020 14:11:21 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/SD-interface-driver-sets-incorrect-SD-clock/m-p/805980#M32363</guid>
      <dc:creator>leecoakley</dc:creator>
      <dc:date>2020-11-02T14:11:21Z</dc:date>
    </item>
  </channel>
</rss>

