Slowing down the SDHC clock

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Slowing down the SDHC clock

3,668 Views
neilporven
Senior Contributor I


Hi everyone, is there a way to slow down the SDHC clock?

 

Thanks,

Neil Porven

Labels (1)
Tags (2)
0 Kudos
25 Replies

2,528 Views
DavidS
NXP Employee
NXP Employee

Hi Neil,

The only intent I had for that example that does use MQX is because it worked on both Freedom and Tower to allow comparison and validation that example works on both too.

For either of the project, all the MQX projects need to be open and built prior to compiling the application.

The easiest method to get all required projects open to compile KSDK_1.3 application is to open the respective *.wsd file from the "Import-->Project of Projects--> Existing Projects Sets" options and click on the *.wsd file.

Ex: C:\Freescale\KSDK_1.3.0\middleware\filesystem\mfs\examples\sdcard\build\kds\sdcard_frdmk64f\sdcard_frdmk64f.wsd

This will open 6 projects!

pastedImage_0.png

Regards,

David

0 Kudos

2,528 Views
neilporven
Senior Contributor I

Hi David,

I had started the same project about a month ago and tried to move to KSDK_2.0_K64F, but I was getting errors during

compiling.  I had to switch back to the KSDK_1.3.0 just to get the project moving, but I wanted to try going back to the

KSDK_2.0_K64F/w KDS_3.1.0. 

Maybe switching to this and trying to slow down the clock could work, if the problem exist within a version issue?

Can you help me get over the compiling issues?

Thanks.

0 Kudos

2,528 Views
neilporven
Senior Contributor I

Hi David,

Update on KSDK_2.0_K64F, there is a driver example located C:\Freescale\SDK_2.0_K64F\boards\frdmk64f\driver_examples\sdcard_fatfs

Looking at the sdcard_fatfs.c file, I find the following:

#if defined BOARD_SDHC_CD_LOGIC_RISING

    while (!(GPIO_ReadPinInput(BOARD_SDHC_CD_GPIO_BASE, BOARD_SDHC_CD_GPIO_PIN)))

    {

    }

where is the function GPIO_ReadPinInput declared?

I looked inside the following:

#include "fsl_uart.h"

#include "fsl_gpio.h"

#include "fsl_debug_console.h"

#include "ff.h"

#include "diskio.h"

#include "board.h"

#include "fsl_mpu.h"

#include "pin_mux.h"

#include "clock_config.h"

could not find it....

thanks,

Neil

0 Kudos

2,529 Views
DavidS
NXP Employee
NXP Employee

Hi Neil,

Sorry for delay.  I was visiting customer yesterday.

The example I was running on the FRDM-K64F will not run on the TWR-K64F.  Too many differences.

But if you want an example that does run on both platforms then:

C:\Freescale\KSDK_1.3.0\middleware\filesystem\mfs\examples\sdcard\build\kds\sdcard_twrk64f120m

C:\Freescale\KSDK_1.3.0\middleware\filesystem\mfs\examples\sdcard\build\kds\sdcard_frdmk64f

Note the SDHC clock setting is based on the SD Card you use.  And even similar cards that get configured with same clocking setting can differ in performance.  I have two such SD Cards where one is 2GB and the other 8GB.  They get setup for 25MHz but the closes configurable clock rate calculates out to 20MHz (I can measure that using o-scope).  The 2GB SD Card will let me write 1234567 bytes in 2 seconds and the 8GB card takes 7 seconds!  Just an observation.

Regards,

David

0 Kudos

2,528 Views
neilporven
Senior Contributor I

Thank you David,

I still haven't figured out the slowing clock issue.  A colleague and I started wondering if its because our bus clock

configuration and how it is down on the FRDM-K64F evaluation board.  This is just a suspicion, since we really can't

understand if everything else is the same, then it should work the same in our custome board.

I did noticed that the example you listed above is a KSDK_1.3.0, that is different from the KSDK_v2, I will try it out

and see what my results are?

Neil

0 Kudos

2,528 Views
neilporven
Senior Contributor I

Quick update,

After looking at the example in the KSDK_1.3.0, I noticed it uses MQX and when I try to compile, I get an

error saying that I am missing the psptypes.h file directory.  I am not using MQX and don't want to be going

that path, since even if I can get the MQX stuff to work, it is not being supported by Freescale or NXP now.

Neil

0 Kudos

2,530 Views
DavidS
NXP Employee
NXP Employee

Hi Neil,

Are you using KSDK_1.2?

If yes I went into it and only modified SDCARD_DRV_InitSd() as follows to change the clocking to 400kHz:

/*FUNCTION****************************************************************

*

* Function Name: SDCARD_DRV_InitSd

* Description: initialize SD memory card

*

*END*********************************************************************/

static sdhc_status_t SDCARD_DRV_InitSd(sdhc_card_t *card)

{

    assert(card);

    sdhc_status_t err = kStatus_SDHC_NoError;

    card->cardType = kCardTypeSd;

    if (kStatus_SDHC_NoError != SDCARD_DRV_AllSendCid(card))

    {

        return kStatus_SDHC_AllSendCidFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendRca(card))

    {

        return kStatus_SDHC_SendRcaFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendCsd(card))

    {

        return kStatus_SDHC_SendCsdFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SelectCard(card, true))

    {

        return kStatus_SDHC_SelectCardFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendScr(card))

    {

        return kStatus_SDHC_SendScrFailed;

    }

    if (kStatus_SDHC_NoError !=

            SDHC_DRV_ConfigClock(card->hostInstance, SDMMC_CLK_400KHZ)) //DES was SDMMC_CLK_25MHZ

    {

        return kStatus_SDHC_SetClockFailed;

    }

    if (DOES_HOST_SUPPORT_4BITS(card->host) && DOES_CARD_SUPPORT_4BITS(card))

    {

        if (kStatus_SDHC_NoError != SDCARD_DRV_SetBusWidth(card, kSdBusWidth4Bit))

        {

            return kStatus_SDHC_SetCardWideBusFailed;

        }

        if (kStatus_SDHC_NoError !=

                SDHC_DRV_SetBusWidth(card->hostInstance, kSdhcBusWidth4Bit))

        {

            return kStatus_SDHC_SetBusWidthFailed;

        }

    }

    if (DOES_HOST_SUPPORT_HIGHSPEED(card->host))

    {

        err = SDCARD_DRV_SwitchHighspeed(card);

        if ((err != kStatus_SDHC_NoError) && (kStatus_SDHC_CardNotSupport != err))

        {

            return kStatus_SDHC_SwitchHighSpeedFailed;

        }

        else if (err == kStatus_SDHC_NoError)

        {

            if (kStatus_SDHC_NoError !=

                    SDHC_DRV_ConfigClock(card->hostInstance, SDMMC_CLK_400KHZ)) //DES was SDMMC_CLK_50MHZ

            {

                return kStatus_SDHC_SetClockFailed;

            }

        }

        else

        {

            err = kStatus_SDHC_NoError;

        }

    }

    if (SDCARD_DRV_SetBlockSize(card, FSL_SDHC_CARD_DEFAULT_BLOCK_SIZE))

    {

        err = kStatus_SDHC_SetCardBlockSizeFailed;

    }

    return err;

}

This project (C:\Freescale\KSDK_1.2.0\examples\twrk64f120m\driver_examples\sdhc_sdcard\kds) sets the clocking up to 120MHz core, 60MHz peripheral and bus, and 24MHz flash.

Regards,

David

0 Kudos

2,530 Views
neilporven
Senior Contributor I

Hi David,

I am actually using the KSDK 1.3.0, but after looking at the function SDCARD_DRV_InitSd

it is the same on both KSDK 1.2.0 and KSDK 1.3.0.  I have changed the same lines you

recommended, but unfortunately the clock doesn't seem to change from the 24MHz?  It

feels like 24MHz is fixed somewhere in the code or a combination of register settings, signals

for 24MHz clock... weird!!!

Is there anything else you can think about that could cause this?

Some background info, I used George Gonzales, sample on setting up the FATfs + SDcard guide,

I believe he made back on 2014 or 2015?  I don't know if this helps any, but I thought the more info

you had the better.

Thank you for keeping track with this issue.

Neil

0 Kudos

2,530 Views
DavidS
NXP Employee
NXP Employee

Hi Neil,

Weird.  I can change the clock, run the example, and measure with o-scope on pin 5 of the SD Card interface clock signal to see it change.  Where are you measuring?

If you step over those clock API's do you see the clocking change on pin 5?  Wondering if it does change it properly but then later the other code modifies it back to 24MHz???  Drawing straws so to speak.

Regards,

David

0 Kudos

2,530 Views
neilporven
Senior Contributor I

Hi David,

I am measuring on PIN 5, my pinout is VDD-4,  DAT0-7,  DAT1-8,  DAT2-1,  CD/DAT3-2, CMD-3

                                                               CLK-5,  SD_SW-9, VSS-6 , the rest are tied to ground.

If I step over the clock API, I can see that the code is responsive.  The reason I know its responsive

is because before the card can be configured with a clock setting, it must be first stopped, then once

the setting has been applied, then the clock is started once again.  If I probe PIN5 while I am stepping

over these lines, I can see the clock stop, then start again.

I didn't try following the code afterwards and watching if when it is configured, it actually switches, I just

let the compiler run (trusting everything was set correctly) and watch to find the very disappointing 24MHz

is still there! LOL.........

I will try to follow it closely and let you know what I find.

thanks,

Neil

0 Kudos

2,530 Views
neilporven
Senior Contributor I

Hi David,

Stepping through the code, I found the following and I would like to confirm it with you to see if you the same.

The code leads me to the following function, which I believe is where the clock actually gets configured.

/*FUNCTION****************************************************************

*

* Function Name: SDHC_HAL_ConfigSdClock

* Description: configure clock of host controller, it will set the most

*      close clock frequency to the given clock

*

*END*********************************************************************/

void SDHC_HAL_ConfigSdClock(SDHC_Type * base, sdhc_hal_sdclk_config_t* clkConfItms)

{

    uint32_t divisor, freq, sysCtlReg;

    assert(base);

    assert(clkConfItms);

    divisor = SDHC_HAL_INITIAL_DVS;

    freq = SDHC_HAL_INITIAL_CLKFS;

    /* Enables the IPG clock and no automatic clock gating off.

     Enables the system clock and no automatic clock gating off.

     Enables the peripheral clock and no automatic clock gating off.

     Enables the SD clock. It should be disabled before changing the SD clock */

    SDHC_CLR_SYSCTL(base, (SDHC_SYSCTL_IPGEN_MASK | SDHC_SYSCTL_HCKEN_MASK | \

      SDHC_SYSCTL_PEREN_MASK | SDHC_SYSCTL_SDCLKEN_MASK));

    /* If user want to disable the clock , directly return. */

    if(!(clkConfItms->enable))

    {

        return;

    }

    if (clkConfItms->destClk > 0)

    {

        while((clkConfItms->maxHostClk / freq / SDHC_HAL_MAX_DVS > clkConfItms->destClk) &&

                (freq < SDHC_HAL_MAX_CLKFS))

        {

            SDHC_HAL_NEXT_CLKFS(freq);

        }

        while((clkConfItms->maxHostClk / freq / divisor > clkConfItms->destClk) &&

                (divisor < SDHC_HAL_MAX_DVS))

        {

            SDHC_HAL_NEXT_DVS(divisor);

        }

        clkConfItms->destClk = clkConfItms->maxHostClk / freq / divisor;         <--------------- Here I see the change happening **********

clkConfItms->destClk = 400KHz coming in, after this line clkConfItms->destClk = 0, then the code continues (I didn't bother copying the rest

it should be the same for you) and finally it gets to this line:

  while(!SDHC_BRD_PRSSTAT_SDSTB(base)) {}

        /* nables the SD clock. It should be disabled before changing the SD clock frequency. */

        SDHC_SET_SYSCTL(base, SDHC_SYSCTL_SDCLKEN_MASK);

If I am holding my probe on the clock (PIN5) I can see that after it passes the while statement, it enables the clock and once again

the 24MHz appears!

In my previous post, I had a concern with this line:

freq = SDHC_HAL_INITIAL_CLKFS;    where    SDHC_HAL_INITIAL_CLKFS = 2U  as seen on fsl_sdhc_hal.h

from the manual, choosing 2U = Base clock divided by 4.

SDCLK Frequency Select

Used to select the frequency of the SDCLK pin. The frequency is not programmed directly. Rather this

register holds the prescaler (this register) and divisor (next register) of the base clock frequency register.

Setting 00h bypasses the frequency prescaler of the SD Clock. Multiple bits must not be set, or the

behavior of this prescaler is undefined. The two default divider values can be calculated by the frequency

of SDHC clock and the following divisor bits.

Table continues on the next page...

Memory map and register definition

K64 Sub-Family Reference Manual, Rev. 2, January 2014

1640 Freescale Semiconductor, Inc.

SDHC_SYSCTL field descriptions (continued)

Field Description

The frequency of SDCLK is set by the following formula: Clock frequency = (Base clock) / (prescaler x

divisor)

For example, if the base clock frequency is 96 MHz, and the target frequency is 25 MHz, then choosing

the prescaler value of 01h and divisor value of 1h will yield 24 MHz, which is the nearest frequency less

than or equal to the target. Similarly, to approach a clock value of 400 kHz, the prescaler value of 08h and

divisor value of eh yields the exact clock value of 400 kHz. The reset value of this field is 80h, so if the

input base clock ( SDHC clock ) is about 96 MHz, the default SD clock after reset is 375 kHz.

According to the SD Physical Specification Version 1.1 and the SDIO Card Specification Version 1.2, the

maximum SD clock frequency is 50 MHz and shall never exceed this limit.

Only the following settings are allowed:

01h Base clock divided by 2.

02h Base clock divided by 4.

04h Base clock divided by 8.

08h Base clock divided by 16.

10h Base clock divided by 32.

20h Base clock divided by 64.

40h Base clock divided by 128.

80h Base clock divided by 256.

I am not sure, if I am heading in the right direction, but I don't understand, if I am changing the same lines as you are,

that I would get a different result?  Of course, this is just a suspicion of what could be happening, maybe it can at least

give you a clue as to why I am not seeing the same thing.

Please let me know your thoughts on this.

Neil Porven

0 Kudos

2,530 Views
neilporven
Senior Contributor I

Update,

David, on the side, I have two FRDM-K64F evaluation boards and a colleague has a TWR system, but he doesn't remember

if he has the K64 top board.  Anyway, I have two questions:

1.  Can I run the TWR example project on the FRDM evaluation board?

2.  Is there a similar example project on the FRDM evaluation board, as in the TWR evaluation board?

I want to compare apples to apples and make sure is not my custom board the one with the issue.

Thanks,

Neil

0 Kudos

2,530 Views
neilporven
Senior Contributor I

Update,

Hi David, so I was able to use the FRDM-K64F evaluation board and using the example project, change the clock

to SDMMC_CLOCK_400KHZ and probe it.  I was able to see the clock change properly. 

At least now, I know I am changing the correct section in code and can see it working, at least on the evaluation board.

Now, I need to figure out what is different from one board to the other, or in software?

KDS_3.1+KSDK_v2 for FRDM-K64F

C:\NXP\KSDK_v2\SDK_2.0_FRDM-K64F_KDS\boards\frdmk64f\driver_examples\sdcard_fatfs\kds

I have two questions regarding this example:

1.  I don't see a main under source, where is the main?

2. What is this project doing?  I don't see anything in the console, I don't see any LEDs blinking??

Thank you

0 Kudos

2,530 Views
neilporven
Senior Contributor I

Update,

On my question 2, I found a Readme.txt file that explains how to work with the project and how to setup

a terminal device.  I did this and it is working.

I am still looking for the link between what is happening between our board/software and the FRDM-K64F board.

Neil

0 Kudos

2,529 Views
DavidS
NXP Employee
NXP Employee

Hi Neil,

Ok...I loaded the KSDK_1.3 C:\Freescale\KSDK_1.3.0\examples\twrk64f120m\driver_examples\sdhc_sdcard\kds example.

In file fsl_sdhc_card.c the following function I only made two edits to set the SD Card frequency to 400KHz and verified it using o-scope. 

static sdhc_status_t SDCARD_DRV_InitSd(sdhc_card_t *card)

{

    assert(card);

    sdhc_status_t err = kStatus_SDHC_NoError;

    card->cardType = kCardTypeSd;

    if (kStatus_SDHC_NoError != SDCARD_DRV_AllSendCid(card))

    {

        return kStatus_SDHC_AllSendCidFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendRca(card))

    {

        return kStatus_SDHC_SendRcaFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendCsd(card))

    {

        return kStatus_SDHC_SendCsdFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SelectCard(card, true))

    {

        return kStatus_SDHC_SelectCardFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendScr(card))

    {

        return kStatus_SDHC_SendScrFailed;

    }

    if (kStatus_SDHC_NoError !=

            SDHC_DRV_ConfigClock(card->hostInstance, SDMMC_CLK_400KHZ)) //DES was SDMMC_CLK_25MHZ))

    {

        return kStatus_SDHC_SetClockFailed;

    }

    if (DOES_HOST_SUPPORT_4BITS(card->host) && DOES_CARD_SUPPORT_4BITS(card))

    {

        if (kStatus_SDHC_NoError != SDCARD_DRV_SetBusWidth(card, kSdBusWidth4Bit))

        {

            return kStatus_SDHC_SetCardWideBusFailed;

        }

        if (kStatus_SDHC_NoError !=

                SDHC_DRV_SetBusWidth(card->hostInstance, kSdhcBusWidth4Bit))

        {

            return kStatus_SDHC_SetBusWidthFailed;

        }

    }

    if (DOES_HOST_SUPPORT_HIGHSPEED(card->host))

    {

        err = SDCARD_DRV_SwitchHighspeed(card);

        if ((err != kStatus_SDHC_NoError) && (kStatus_SDHC_CardNotSupport != err))

        {

            return kStatus_SDHC_SwitchHighSpeedFailed;

        }

        else if (err == kStatus_SDHC_NoError)

        {

            if (kStatus_SDHC_NoError !=

                    SDHC_DRV_ConfigClock(card->hostInstance, SDMMC_CLK_400KHZ)) //DES was SDMMC_CLK_50MHZ))

            {

                return kStatus_SDHC_SetClockFailed;

            }

        }

        else

        {

            err = kStatus_SDHC_NoError;

        }

    }

    if (SDCARD_DRV_SetBlockSize(card, FSL_SDHC_CARD_DEFAULT_BLOCK_SIZE))

    {

        err = kStatus_SDHC_SetCardBlockSizeFailed;

    }

    return err;

}

Terminal Output attached for running default example and example at 400KHz.

Regards,

David

0 Kudos

2,529 Views
neilporven
Senior Contributor I

Hi David,

I can see there are two location on my fsl_sdhc_card.c

where I can change the clock, here is one:

/*FUNCTION****************************************************************

*

* Function Name: SDCARD_DRV_Init

* Description: initialize card on the given host controller

*

*END*********************************************************************/

sdhc_status_t SDCARD_DRV_Init(sdhc_host_t *host, sdhc_card_t *card)

{

    sdhc_status_t err = kStatus_SDHC_NoError;

    uint32_t acmd41Arg;

    assert(card);

    assert(host);

    card->cardType = kCardTypeUnknown;

    card->host = host;

    card->hostInstance = host->instance;

    if (SDHC_DRV_ConfigClock(card->hostInstance, SDMMC_CLK_400KHZ))

    {

        return kStatus_SDHC_SetClockFailed;

    }

    err = SDCARD_DRV_GoIdle(card);

    if (err)

    {

        return kStatus_SDHC_SetCardToIdle;

    }

    acmd41Arg = card->host->ocrSupported;

    err = SDCARD_DRV_SendIfCond(card);

    if (err == kStatus_SDHC_NoError)

    {

        /* SDHC or SDXC card */

        acmd41Arg |= SD_OCR_HCS;

        card->caps |= SDMMC_CARD_CAPS_SDHC;

    }

    else

    {

        /* SDSC card */

        err = SDCARD_DRV_GoIdle(card);

        if (err)

        {

            return kStatus_SDHC_SetCardToIdle;

        }

    }

    err = SDCARD_DRV_AppSendOpCond(card, acmd41Arg);

    if (kStatus_SDHC_TimeoutError == err)

    {

        /* MMC card */

        return kStatus_SDHC_NotSupportYet;

    }

    else if (err)

    {

        return kStatus_SDHC_SendAppOpCondFailed;

    }

    return SDCARD_DRV_InitSd(card);

}

also, I this one:

/*FUNCTION****************************************************************

*

* Function Name: SDCARD_DRV_InitSd

* Description: initialize SD memory card

*

*END*********************************************************************/

static sdhc_status_t SDCARD_DRV_InitSd(sdhc_card_t *card)

{

    assert(card);

    sdhc_status_t err = kStatus_SDHC_NoError;

    card->cardType = kCardTypeSd;

    if (kStatus_SDHC_NoError != SDCARD_DRV_AllSendCid(card))

    {

        return kStatus_SDHC_AllSendCidFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendRca(card))

    {

        return kStatus_SDHC_SendRcaFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendCsd(card))

    {

        return kStatus_SDHC_SendCsdFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SelectCard(card, true))

    {

        return kStatus_SDHC_SelectCardFailed;

    }

    if (kStatus_SDHC_NoError != SDCARD_DRV_SendScr(card))

    {

        return kStatus_SDHC_SendScrFailed;

    }

    if (kStatus_SDHC_NoError !=

            SDHC_DRV_ConfigClock(card->hostInstance, SDMMC_CLK_400KHZ))

    {

        return kStatus_SDHC_SetClockFailed;

    }

    if (DOES_HOST_SUPPORT_4BITS(card->host) && DOES_CARD_SUPPORT_4BITS(card))

    {

        if (kStatus_SDHC_NoError != SDCARD_DRV_SetBusWidth(card, kSdBusWidth4Bit))

        {

            return kStatus_SDHC_SetCardWideBusFailed;

        }

        if (kStatus_SDHC_NoError !=

                SDHC_DRV_SetBusWidth(card->hostInstance, kSdhcBusWidth4Bit))

        {

            return kStatus_SDHC_SetBusWidthFailed;

        }

    }

    if (DOES_HOST_SUPPORT_HIGHSPEED(card->host))

    {

        err = SDCARD_DRV_SwitchHighspeed(card);

        if ((err != kStatus_SDHC_NoError) && (kStatus_SDHC_CardNotSupport != err))

        {

            return kStatus_SDHC_SwitchHighSpeedFailed;

        }

        else if (err == kStatus_SDHC_NoError)

        {

            if (kStatus_SDHC_NoError !=

                    SDHC_DRV_ConfigClock(card->hostInstance, SDMMC_CLK_400KHZ))

            {

                return kStatus_SDHC_SetClockFailed;

            }

        }

        else

        {

            err = kStatus_SDHC_NoError;

        }

    }

    if (SDCARD_DRV_SetBlockSize(card, FSL_SDHC_CARD_DEFAULT_BLOCK_SIZE))

    {

        err = kStatus_SDHC_SetCardBlockSizeFailed;

    }

    return err;

}

As you can see, I changed both.  Is it needed for the first one as well?

Do you have a similar function for the twrk64?

Thank you,

Neil

0 Kudos

2,529 Views
neilporven
Senior Contributor I

Hi David,

Its seems that 24MHz is all I can get.  By the way, I am using my own board and my internal bus clock is 48MHz.

Thanks,

Neil

0 Kudos

2,529 Views
neilporven
Senior Contributor I

Quick update,

I think the twrk64 example is running an internal BUS clock of 4MHz and its being derived from the external oscillator.

I also noticed that the example does have  SDCARD_DRV_Init and the internal clock is set to 400KHZ.

Do you believe the DIV needs to be set in my case running a 48MHZ clock?

thanks,

Neil

0 Kudos

2,529 Views
neilporven
Senior Contributor I

Another update,

I noticed that fsl_sdhc_hal.c  has the following function:

void SDHC_HAL_ConfigSdClock(SDHC_Type * base, sdhc_hal_sdclk_config_t* clkConfItms)

It contains these two lines:

divisor = SDHC_HAL_INITIAL_DVS;

freq = SDHC_HAL_INITIAL_CLKFS;

SDHC_HAL_INITIAL_DVS is pre-defined to 1U

SDHC_HAL_INITIAL_CLKFS is pre-defined to 2U

trying to change these values inside the KDS, does absolutely nothing!  I am trying to set them so:

SDHC_HAL_INITIAL_DVS is 0U  (divide by 1)

SDHC_HAL_INITIAL_CLKFS is 40U (divide by 128)

with my internal bus running at 48MHz it should roughly give me 375KHz.

Neil

0 Kudos

2,529 Views
DavidS
NXP Employee
NXP Employee

Hi Neil,

I'm testing with KDS_3.1+KSDK_v2 for FRDM-K64F and running the example C:\NXP\KSDK_v2\SDK_2.0_FRDM-K64F_KDS\boards\frdmk64f\driver_examples\sdcard_fatfs\kds .

In the fls_sd.c file SD_Init() function is around line 1011.  This routine identifies the SD Card being used to determine what maximum clock rate to use.  My test card is 2GB and can operate at high speed clocking (50MHz setting but 30MHz implemented).

The default 400KHz SD Card clocking is used to identify card and then the clock is increased and tested to see if it can go higher (my summary of the code).

Stepping through that code I found my card would get to line 1123 and try to set clock to 50MHz.

        else if (error == kStatus_Success)

        {

            card->busClock_Hz = SDHC_SetSdClock(card->host.base, card->host.sourceClock_Hz, SD_CLOCK_50MHZ);

        }

When I measured with Oscope it was 30MHz.

Now when I replace that code with following:

        else if (error == kStatus_Success)

        {

            card->busClock_Hz = SDHC_SetSdClock(card->host.base, card->host.sourceClock_Hz, SDMMC_CLOCK_400KHZ); //DES was SD_CLOCK_50MHZ);

        }

Now when I measure I get 375kHZ and the example worked fine (just slower).

For your case you should be able to step through the code to see what clock rate it is determining your card can handle and then adjust down as you see fit.

Regards,

David

0 Kudos