Home > FRDM K64F, Kinetis > FRDM K64F Data Logger using FatFs with KSDK 1.2.0

FRDM K64F Data Logger using FatFs with KSDK 1.2.0

This blog is a guide on how to setup using the FatFs library included with the Kinetis SDK 1.2.0 using mostly the Processor expert within Eclipse Luna. FatFs is a generic FAT file system module for small embedded systems written by Chan. I prefer to use Processor Expert when possible as this will often generate code that is smaller in size than using the KSDK library files direct. I experienced many gotcha’s and complication setting this up and wanted to share how I finally managed to get it to work.

  1. Prerequisites
  2. Create New Project
  3. Open Processor Expert
  4. Add SD card component
  5. Add Init_Port component
  6. Add GPIO component
  7. Configure the clock
  8. Import FatFs
  9. Add Card detection code
  10. FAT file appender function
  11. Disable the MPU

Prerequisites

Before you begin please make sure your development environment is setup and you can already compile and debug code using KSDK 1.2.0 on Eclipse Luna. If not please refer to my blog: Toolchain: KSDK 1.2.0 with Eclipse 4.4 (Luna) and GNU ARM Plugin

 

Create New Project

  1. Within Eclipse, on the top menu point your mouse over “File” menu item, this should expand out with an option to select “Kinetis Project”.

    NewKinetisProject

  2. Name your project, I tend to name my project starting with the type of development board or processor followed by an underscore and then purpose of the project, this allows me to create projects of the same purpose for other boards/processors. Set location of project, I use the default location under the workspace area. Click Next.

    NameProject

  3. Select the development board used, and click Next.

    DevelopmentBoard

  4. Select “KSDK 1.2.0”. Set location to KSDK path, I use an absolute path but you can select Environment variable if you have set up a path under Windows operating system environment variables with a name called “KSDK_PATH” that points to the location of the KSDK folder. The location of my KSDK is in the default location where KSDK would install to.
    Ensure “Processor Expert” checkbox is checked. The perspective radio button you select does not matter nor does the Project mode for this project. Click the Next button.

    SDKandPESelect

  5. Select “GNU C Compiler” and Click the “Finish” button.

    SelectGNUCompiler

    N.B. Wait a while for Processor Expert to finish generating the initial source for the project. Keep an eye on the progress when it reaches 100% by looking at the bottom right hand corner of Eclipse.

    GeneratingCode

Open Processor Expert

Before you proceed make sure you can build the project now without errors. If not then make sure you have followed the instructions and understood how to setup your Eclipse environment as specified in the blog Toolchain: KSDK 1.2.0 with Eclipse 4.4 (Luna) and GNU ARM Plugin, especially the “Setting Eclipse workspace preferences” section.

  1. Open the Processor Expert perspective, this should be a button on the top right hand side of Eclipse.

    OpenPEPerspective

    If it’s not there, try clicking on the “Open Perspective” button and then selecting “Processor Expert” in the form that appears.

    OpenPerspective

    AddPEPerspective

Add SD Card component

  1. Click on the “Components Library” tab, search for the component “fsl_sdcard” and double click on it.

    component_fsl_sdcard

  2. Select the “memoryCard1:fsl_sdcard” in the Components window.

    select_memoryCard1

  3. Click on the “Component Inspector” tab. Then select the Initialization tab. Untick the “Auto initialization” check box. This is very important as the FatFs component will perform this step for us instead. Actually even if you don’t use FatFs you would perform this step manually every time you wanted to open a file on the sd card.

    sdCard_disable_initialise

  4. Now back on the Components window, expand the “memoryCard1:fsl_sdcard” component and select the “fsl_sdhc1:fsl_sdhc” component.

    select_fsl_sdhc1

  5. Click on the “Component Inspector” tab. Then select the “Configurations” tab, then select “ADMA2” for the transfer mode. Ensure “GPIO” is selected for the Card detection type. The FRDM K64F board’s SD card reader is wired with a switch connected to PTE6 to detect when a card is inserted. The SD card reader itself can also detect card insertion but it is easier to setup and use the GPIO pin.

    Don’t worry that the Bus clock is set to 400 kHz, this ultimately gets geared up to 50 MHz when the fsl_sdcard component is initialised. You won’t see this code in this example but basically when the FatFs component opens a file it performs a mounting check on the SD card and within that check it initialises the fsl_sdcard where it under goes a gearing up of different speeds on the SD card, first at 100 kHz, then 400 kHz, then 25 MHz and finally 50 MHz.

    set_ADMA2

  6. Now switch to the “Pins” tab. Refer to the FRDM-K64F Freedom Module User’s Guide at section 7 “Secure digital card” and map the pins as specified. 

    fsl_sdhc_pins

  7. Now switch to the “Initialization” tab. We need to ensure we generate a handler for interrupt service routine as this gets used by the fsl_sdcard initialisation. We cannot add a handler unless we first enable “Auto initialisation” then tick the check box “Install interrupts”. There is no particular need to “Auto initialise” other than to be able to install the interrupt. I expect future versions of the KSDK will probably separate these 2 properties. Luckily there is no harm caused enabling the “Auto initialization” as the initialisation code of the fsl_sdcard routine first shuts down the fsl_sdhc and then re-initialises it.

    fsl_sdhc_initialization

Add Init_Port component

  1. Click on the “Components Library” tab, search for the component “Init_Port” and double click on it.

    component_Init_PORT

  2. Select the “PORTA:Init_PORT” in the Components window.

    select_Init_Port

  3. Click on the “Component Inspector” tab. Change Device to “PORTE”, Enable Clock gate, Initialize Pin 0, set Mux control to “SDHC01_D1”.

    For Pins 0 to 5 refer to section “3.9.7.2 SD bus pullup/pulldown constraints” within the K64 reference manual K64P144M120SF5RM, this section explains that the Pull resistor setting needs to be enabled and the Pull selection needs to “Pull Up”.

    I couldn’t find where its documented but I discovered that the SD card host cannot run at 50 MHz unless the slew rate is set to “Fast” and the Drive strength set to “High”.

    Init_PORT_Pin0_settings 

Add GPIO component

  1. Click on the “Components Library” tab, search for the component “fsl_gpio” and double click on it. 

    component_fsl_gpio

  2. Select the “gpio1:fsl_gpio” in the Components window. 

    select_gpio1

  3. Click on the “Component Inspector” tab. Select the Input pins tab. Under the Input configuration 0 section change the Pin to “SD_CARD_DETECT”  which is also known as the PTE6 pin. We need to detect when the SD card is inserted so we will need an interrupt on this pin, select “Interrupt on either edge” under the Interrupt/DMA section. Refer to the FRDM-K64F Freedom Module User’s Guide at section 7 “Secure digital card”. In this section it states that the pin shorts with VDD when the card is inserted. Thus we must ensure the Pin is pulled down. Tick the Pull enable check box and set the Pull select direction to “Down”. Untick the Passive filter and Digital filter.

    fsl_gpio_Input

  4. Select the “Output pins” tab. Untick the Output pins check box. We do not need to configure any output pins as GPIO.

    fsl_gpio_Output

  5. Select the “Initialization” tab, Ensure “Auto initialization” and “Input pins” check box is ticked. Untick the “Output pins” check box. Now notice here under the Interrupts section that the interrupt for PORTE is disabled. See the next step to enable it.

    fsl_gpio_Init1

  6. To enable the PORTE interrupt, select the “Events” tab and then select “generate code” next to PORTE IRQ handler. If you switch back to the Properties tab you should see the PORTE interrupt is now enabled.

    fsl_gpio_Events 

Configure the clock

In order to get the maximum speed of 50 MHz on the SD card, we need to ensure the host system clock is running faster than this. For this reason I recommend configuring the system clock to run at 100 MHz.

  1. Select the “clockMan1:fsl_clock_manager” in the Components window.

    select_clockMan1

  2. Click on the “Component Inspector” tab. Under it select Initialization tab. Select “clockMan1_InitConfig5” in the drop down field “Init clock configuration”.

    fsl_clock_manager_Init

  3. If you don’t have the default clock configurations then make sure you configure a clock source with the details below.

    fsl_clock_manager_Sources
    fsl_clock_manager_InternalRef
    fsl_clock_manager_ExternalRef
    fsl_clock_manager_MCG
    fsl_clock_manager_SystemClocks

    With this configuration you can see the Core clock will run at 100 MHz.

Import FatFs

  1. At this point we have done all we can within Processor Expert. Make sure you save all on the project at this point then on the Components window, click on the Generate code button.

    GenerateCode

  2. Build the project and make sure there are no errors.
  3. Right click on the project in the project explorer and Add a New Folder. Name the folder “Middleware”.

    NewFolder

    NewFolder_Middleware

  4. Right click on the Middleware folder within the Project Explorer window. Select Import.

    Import

  5. Under the General folder select “File System” and click Next.

    Import_FileSystem

  6. Click the “Browse…” button and navigate to where you have installed KSDK 1.2.0. Under the KSDK folder navigate into the “middleware folder, then the filesystem folder and then select the fatfs folder and click the OK button.

    Import_Browse

  7. Now don’t import the whole FatFs directory, this will not work. Instead select the files as follows:

    Import_FatFs1

    Import_FatFs2

    Import_FatFs3

  8. Now we need to add all the header files from this library to the project. Right click on the project in Project Explorer and select properties. Then expand the C/C++ Build folder in the left part of the window and select “Settings”. On the right side select “Includes” under the “Cross ARM C Compiler” section. Now click on the Add button and add the directories "${ProjDirPath}/Middleware/fatfs" and "${ProjDirPath}/Middleware/fatfs/fsl_sd_disk"

    Includes_FatFs1

    Includes_FatFs2 

  9. The FatFs library needs to be told how you are detecting the SD card has been inserted, it also wants to know if you are using USB or SD card for storage. You need to add Preprocessor symbols to resolve this. On the Project properties window again under “C/C++ Build”-> “Settings”->”Cross ARM C Compiler” but this time select “Preprocessor”. Click the Add button and add the symbol “CD_USING_GPIO” and also “SD_DISK_ENABLE=1”

    Preprocessor_CD_USING_GPIO

    Preprocessor_SD_DISK_ENABLE

Add Card detection code

Look for the file Events.h under the sources folder in your project. Notice this file contains a interrupt handler for Port E. We need to use this for detecting when the SD card is inserted. In this file Add 2 more functions that we will need, check_card_inserted() and wait_for_card().

/* ###################################################################
**     Filename    : Events.h
**     Project     : K64F_DataLogger
**     Processor   : MK64FN1M0VLL12
**     Component   : Events
**     Version     : Driver 01.00
**     Compiler    : GNU C Compiler
**     Date/Time   : 2015-06-26, 18:12, # CodeGen: 0
**     Abstract    :
**         This is user's event module.
**         Put your event handler code here.
**     Settings    :
**     Contents    :
**         No public methods
**
** ###################################################################*/
/*!
** @file Events.h
** @version 01.00
** @brief
**         This is user's event module.
**         Put your event handler code here.
*/         
/*!
**  @addtogroup Events_module Events module documentation
**  @{
*/         

#ifndef __Events_H
#define __Events_H
/* MODULE Events */

#include "fsl_device_registers.h"
#include "clockMan1.h"
#include "pin_init.h"
#include "osa1.h"
#include "memoryCard1.h"
#include "fsl_sdhc1.h"
#include "gpio1.h"

#ifdef __cplusplus
extern "C" {
#endif 


void PORTE_IRQHandler(void);

void fsl_sdhc1_OnCardDetect0(bool inserted);

void fsl_sdhc1_OnCardInterrupt0(void);

void fsl_sdhc1_OnCardBlockGap0(void);

void check_card_inserted(void);
void wait_for_card(void);

/* END Events */

#ifdef __cplusplus
}  /* extern "C" */
#endif 

#endif 
/* ifndef __Events_H*/
/*!
** @}
*/
/*
** ###################################################################
**
**     This file was created by Processor Expert 10.5 [05.21]
**     for the Freescale Kinetis series of microcontrollers.
**
** ###################################################################
*/

 

Now update the Events.c file to look like the following:

/* ###################################################################
 **     Filename    : Events.c
 **     Project     : K64F_DataLogger
 **     Processor   : MK64FN1M0VLL12
 **     Component   : Events
 **     Version     : Driver 01.00
 **     Compiler    : GNU C Compiler
 **     Date/Time   : 2015-06-26, 18:12, # CodeGen: 0
 **     Abstract    :
 **         This is user's event module.
 **         Put your event handler code here.
 **     Settings    :
 **     Contents    :
 **         No public methods
 **
 ** ###################################################################*/
/*!
 ** @file Events.c
 ** @version 01.00
 ** @brief
 **         This is user's event module.
 **         Put your event handler code here.
 */
/*!
 **  @addtogroup Events_module Events module documentation
 **  @{
 */
/* MODULE Events */

#include "Cpu.h"
#include "Events.h"

#ifdef __cplusplus
extern "C" {
#endif 


/* User includes (#include below this line is not maintained by Processor Expert) */

static volatile bool cardInserted = false; /* Flag to indicate a card has been inserted */

void PORTE_IRQHandler(void)
{
	if(PORT_HAL_GetPortIntFlag(PORTE_BASE_PTR) == (1<<SD_CARD_DETECT))
	{
		check_card_inserted();
	}

	PORT_HAL_ClearPortIntFlag(PORTE_BASE_PTR);
}

void fsl_sdhc1_OnCardDetect0(bool inserted)
{
	/* Write your code here ... */
}

void fsl_sdhc1_OnCardInterrupt0(void)
{
	/* Write your code here ... */
}

void fsl_sdhc1_OnCardBlockGap0(void)
{
	/* Write your code here ... */
}

void check_card_inserted(void)
{
	uint32_t state = GPIO_DRV_ReadPinInput(SD_CARD_DETECT);
	uint32_t matchState = -1;

	// Debounce input
	do
	{
		for (int i = 0; i < 0x1FFFFF; i++)
		{
			__asm("nop");
		}
		matchState = state;
		state = GPIO_DRV_ReadPinInput(SD_CARD_DETECT);
	}
	while (state != matchState);

	// Set card state
	cardInserted = (state == 1);

	fsl_sdhc1_OnCardDetect0(cardInserted);
}

void wait_for_card(void)
{
	while ((!cardInserted));
}

/* END Events */

#ifdef __cplusplus
}  /* extern "C" */
#endif 

/*!
 ** @}
 */
/*
 ** ###################################################################
 **
 **     This file was created by Processor Expert 10.5 [05.21]
 **     for the Freescale Kinetis series of microcontrollers.
 **
 ** ###################################################################
 */

Here we are using the Port E interrupt handler function called PORTE_IRQHandler to check if an interrupt happened on the SD card detect pin (Port E Pin 6). If so then we check the pin to see if the card was inserted or removed by using the function check_card_inserted. after checking the card the handler must ensure the interrupt flag is reset to handle further interrupts.

The check_card_inserted function reads the state on SD card detect pin, it then performs a process of repeatedly reading the state of this pin after a short delayed period until previous reads and current reads match. Once they match then it should mean that the pin has stopped bouncing and the final state value is the true current state. We then store this state as a boolean type in the variable cardInserted. Later in the main.c file we will call into the function wait_for_card where we read and wait for the value on the cardInserted to equal true at which point we know the card is inserted and can perform operations on the card.

 

FAT file appender function

Update the main.c file to look like the following:

/* ###################################################################
 **     Filename    : main.c
 **     Project     : K64F_DataLogger
 **     Processor   : MK64FN1M0VLL12
 **     Version     : Driver 01.01
 **     Compiler    : GNU C Compiler
 **     Date/Time   : 2015-06-26, 18:12, # CodeGen: 0
 **     Abstract    :
 **         Main module.
 **         This module contains user's application code.
 **     Settings    :
 **     Contents    :
 **         No public methods
 **
 ** ###################################################################*/
/*!
 ** @file main.c
 ** @version 01.01
 ** @brief
 **         Main module.
 **         This module contains user's application code.
 */
/*!
 **  @addtogroup main_module main module documentation
 **  @{
 */
/* MODULE main */


/* Including needed modules to compile this module/procedure */
#include "Cpu.h"
#include "Events.h"
#include "clockMan1.h"
#include "pin_init.h"
#include "osa1.h"
#include "memoryCard1.h"
#include "fsl_sdhc1.h"
#include "gpio1.h"
#if CPU_INIT_CONFIG
#include "Init_Config.h"
#endif
/* User includes (#include below this line is not maintained by Processor Expert) */

#include <string.h>
#include "ff.h"

#define		SD_DRIVE_NUMBER		1

void append(char *fileNameAndPath, char *text)
{
	FATFS fileSystem;

	// mount SD card
	FRESULT fResult = f_mount(SD_DRIVE_NUMBER, &fileSystem);

	if (fResult == FR_OK)
	{
		fResult = f_chdrive(SD_DRIVE_NUMBER);

		if (fResult == FR_OK)
		{
			FIL file;
			static char pathWithDriveLetter[255];
			sprintf(pathWithDriveLetter, "%u:%s", SD_DRIVE_NUMBER, fileNameAndPath);

			/* Open a text file */
			fResult = f_open(&file, pathWithDriveLetter, FA_OPEN_ALWAYS | FA_WRITE);
			if (fResult == FR_OK)
			{
				/* Move to end of the file to append data */
				fResult = f_lseek(&file, file.fsize);

				/* Write to the file */
				uint32_t bytesWritten;
				fResult = f_write(&file, text, strlen(text), &bytesWritten);
			}
			/* Close the file */
			fResult = f_close(&file);
		}

		// unmount SD card
		fResult = f_mount(SD_DRIVE_NUMBER, NULL);
	}
}

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */
int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
	/* Write your local variable definition here */

	/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
	PE_low_level_init();
	/*** End of Processor Expert internal initialization.                    ***/

	// Check card is already inserted and don't wait for interrupt
	check_card_inserted();

	// If card is not inserted then we must wait till it is inserted
	wait_for_card();

	append("/data.log", "test data");

	/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;){}
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

/* END main */
/*!
 ** @}
 */
/*
 ** ###################################################################
 **
 **     This file was created by Processor Expert 10.5 [05.21]
 **     for the Freescale Kinetis series of microcontrollers.
 **
 ** ###################################################################
 */

 

Here in the main function we make use of the check_card_inserted and wait_for_card function we created in the Events.c file. Once the SD card is inserted we call a new function added to this main.c file called append. The append function’s responsibility is to mount the SD card, open a file at a given path on the SD card, if the file does not exist it will create it, then it will move to the end of the file and append some given text to the file. It will then close the file and unmount the SD card so that the append function can repeatedly be called.

 

Disable the MPU

If you place a breakpoint on line 68 in the main.c file just after where it calls the f_open function then compile, run the application and observer the value of the fResult, then you will see it failed to open the file and returned a value of FR_NOT_READY. The reason this happens is because the Memory Protection Unit (MPU) is enabled by default on the K64 controller and is preventing bus master accesses to the SDHC memory areas. Configuring the MPU areas is a blog for another day but it is safe to simply disable the MPU.

  1. Open the Processor Expert perspective again. Click on the “Components Library” tab, search for the component “Init_MPU” and double click on it.  

    component_Init_MPU

  2. Select the “MPU:Init_MPU” in the Components window.  

    select_Init_MPU

  3. Click on the “Component Inspector” tab. Enable the clock gate and untick the "MPU module" checkbox. That will disable the MPU.

    Init_MPU_disable

  4. click on the Generate code button.

    GenerateCode 

  5. Build the project and make sure there are no errors.

You should now be able to run the application successfully. Once you have run it, eject the SD card and insert it into your computer. You should now see a file on the SD card called "data.log". If you open the file it should contain one or more lines of text saying "test data".

 

Well done if you managed to follow along and get it all working, I spent many days working this one out so I hope this blog helps others. As a bonus you may want to try figure out how to add a real time clock to your project and use it within the FatFs library. If you look at what the last modified date is of data.log file, then you will notice it always equals 1 Jan 2010 no matter how many times you run the application or when you run the application. This is because the kinetis FatFs library hard codes it to this value. To fix it you can add a RTC component to your project and then search for the function "get_fattime" within diskio.c file and replace the logic there to make use of your RTC component.

Advertisements
  1. 29/07/2015 at 05:54

    Excellent tutorial! I have created my own FatFS Processor Expert component to make using FatFS easier (http://mcuoneclipse.com/2012/07/30/fatfs-with-kinetis/), but I had no time yet to adopt it as such that it works with the Kinetis SDK, as the API is different. I think your tutorial should help me to make that transition, so thank you!

    • 29/07/2015 at 07:38

      Thanks Erich. Your blogs were invaluable to me. I’m not sure I would have figured some of these bits out without your blogs. I look forward to seeing your updated FatFs component using KSDK, that will save everyone a lot of time.

  2. 29/07/2015 at 05:58

    Reblogged this on MCU on Eclipse and commented:
    Check out the article by Wesley Hunter about how to use the FRDM-K64F as a data logger. He describes all the steps how to use the Kinetis SDK v1.2.0 with FatFS.

    Happy Logging 🙂

  3. Michael Lyons
    30/07/2015 at 13:57

    This is a great post! I was trying to use the fsl_sdcard with SPI on the FRDM-KL25Z and ran into a couple problems. You wouldn’t happen to know where a tutorial for that would be do you? Also, I would love to see the datalogger implemented in freeRTOS or MQX if you ever get the chance.

    Thanks,
    Michael

    • 31/07/2015 at 07:32

      Hi Michael. Unfortunately I have not tried using fsl_card with SPI yet and I also don’t know of any good blog posts for it but I learnt a lot about how to solve the problems I had with the SD card by looking through a lot of the code in the KSDK example projects. I noticed there is a “SPI SDCard Example” project in KSDK 1.2.0, have you tried looking at that yet?

      • Michael
        28/10/2015 at 22:04

        Hi, Thanks for the reply. I cannot find that example in my KSDK_1.2.0 folder. Could you please share where it is?

      • 29/10/2015 at 09:39

        Hi Michael. Unfortunately the example is not for the K64F but I find you can often tweak configurations in the examples to work for your board. An example can be found under .\KSDK_1.2.0\examples\twrk24f120m\driver_examples\spi_sdcard\kds.
        You can find a little bit of documentation on this example in chapter 59 of the “Kinetis SDK v.1.2.0 Demo Applications User’s Guide.pdf” found in .\Freescale\KSDK_1.2.0\doc

  4. Bob Kohan
    08/08/2015 at 17:54

    I am using KDS3.0 & KSDK1.2 and trying to follow your instructions for data logger project. I get the following error: “fatal error: fsl_dspi_edma_master_driver.h: No such file or directory fsl_sdspi_disk.c /K64F_DataLogger/Middleware/fatfs/fsl_sd_disk/src line 38 C/C++ Problem”. What am I missing?

    • 08/08/2015 at 19:41

      Hi Bob. I think you imported the FatFs dspi libraries as well. Don’t import both the dspi and sd_disk files from the FatFs library. Go back to the “Import FatFs” section in my blog and only import the files in each directory that I have ticked in my screen shots. Note that I do not tick the directories “fsl_usb_disk”, “option” and the file “fsl_sdspi_disk.c” from the “src” directory. By the way, I think you probably just imported this last file by mistake. Hope you come right.

  5. 15/09/2015 at 21:53

    Hello Wesley, fantastic thank you so much for the blog -very nicely defined.
    I’ve just brought up a new PCB with a Kinetis MK26FN2 processor and followed your tutorial – and it worked.
    This was such a fantastic learning experience to be able to work through your example for a feeling for the SDK1.2 and get a working basic framework.
    The clocks for a MK26FN are different but still worked following your example
    I’m going to try adjust your for example for a USB Host MSC as it seems to support that,
    and then try and port/import the frdmk64_usb_msd.zip made available here
    https://community.freescale.com/thread/353811
    I verified it works very easily on a FRDM-K64 board – reads/writes the SDcard from the USB.
    and finally see if they can be combined into an OTG set
    One minor issue
    the compiler complained at your *bytesWritten – I believe it should be a variable not a a pointer.
    /* Write to the file */
    uint32_t bytesWritten;
    fResult = f_write(&file, text, strlen(text), &bytesWritten);

    BTW – I’m a Zimbo living in Ca. 🙂 The world’s a small place.

    • 16/09/2015 at 08:37

      Thanks Neil. Sounds like a great project you working on, perhaps feedback how its going or a blog of your own. I will take a closer look at that bytesWritten later today.

    • 29/09/2015 at 09:24

      Hi Neil. Finally had a look at that bytesWritten and you were right it should be a variable. I have updated the post, thanks.

  6. Ting
    16/11/2015 at 03:44

    I am using KDS3.0 & KSDK1.2 and trying to follow your instructions for data logger project. Before i add the step of disable the MPU. it calls the f_open function failed and returned a value of FR_NOT_READY as your instructions, but then i disable the MPU, f_open function can not returned, i track it, and found the forever while can’t returned:

    /* Wait until last time sdhc send operation complete */
    while(!SDHC_HAL_GetCurState(g_sdhcBase[instance], kSdhcHalGetDataLine0Level)){}

    how can i fix it? thanks in advance!

    • 16/11/2015 at 08:39

      Hi Ting. Unfortunately I have not had this error myself so not sure what it could be but I suspect your Pins are not pulling in the right direction or do not have a high drive strength. Double check the section “Add Init_Port component” in my tutorial and make sure you have set all the PTE Pins 1,2,3,4 and 5 to have Pull up resistor, fast slew rate and a high drive strength.

      • Ting
        16/11/2015 at 09:04

        Yes, you are so smart, i have not set all PTE pins from 1~5, after i set it, the f_open() can returned, but return error code FR_INVALID_NAME, do you have any idea about the error code? thank you so much!

      • 16/11/2015 at 09:27

        Yes the problem is the name of the file. Unfortunately FatFs is not very good at working with files with more than very simple name formats. i.e. I have found if a file has more than one dot “.” or underscore “_” in it then it cannot open the file. Start with basic file names like “Data.Log” and work in the root folder to begin with. Get that working first then work your way up from there.

        Ting, also be careful that your path also includes the drive letter/number, i.e. f_open(&file, “1:/Data.Log”, FA_OPEN_ALWAYS | FA_WRITE);

        Note the “1:”, my append function caters for this by using sprintf to pre-pend the drive letter onto the file name. If you are not using my append function then note you will need provide this drive letter as well.

      • Ting
        17/11/2015 at 01:06

        Yes, you are right once again, the problem is the name of the file, excpet the . and _, the length of the name must very short, my project can work with basic name. thank you so much for your excellent tutorial!

  7. Hung
    16/11/2015 at 07:42

    thanks a lot for this excellent and tutorial. Unlike others, it is very detailed without any jumps in description. That makes it easy to reproduce it. I wonder if you also have such a tutorial for USB using KSDK1.2? thanks again

    • 16/11/2015 at 08:47

      Sorry Hung, unfortunately I do not. USB can be quite a large topic, what is it you want to do with the usb. For instance, do you want to simply communicate out debug type statements through your usb port, do you want to create a mass storage device so you can store files on your device, do you want to use the usb to have extrenal devices connected to it. You see what I mean, each of those examples would be tutorials of their own.

  8. Hung
    16/11/2015 at 11:02

    I am interested in communication between k64f and pc using the USB port of the mcu (not the open sda).

  9. Hung
    26/11/2015 at 11:12

    hope, you will post it soon. I have tried out Eric’s work. However, lall of my computers didn’t accept the usb driver.

  10. Ting
    02/12/2015 at 06:11

    My project can work following your excellent tutorial, then i want to using MQX, but after i update the osa PE components as MQX_Standard, the append() function will break when call f_open(), and the firmware will restart to execute main(). Does anyone know why? Thanks!!

  11. Hung
    25/12/2015 at 15:45

    Thanks a lot for the new posting about USB!!! I haven’t tried it out, yet, but definitely will!

  12. 23/02/2016 at 04:34

    Hello, I went through this great tutorial, I had some errors which I finally corrected. I am not getting any test files written to the microSD via the K64. I am using KDS 3.0 and KDSK 1.3.0. I am able to build with a couple of warning but no errors. The warnings are: MQX_OS needs install component interrupt service routines and This value is not available on this device but is configurable in static driver. I believe these warnings could be due to components I added to the project but do not think it should affect the microSD portion. I was wondering if there were anything specific I should check to verify that the K64 / the program does see the microSD card. I have gone through all the settings and everything seems to match up. Just wanted to see if there were any tips for this. Again the project builds with no errors just the 2 warnings I stated. Thank you.

    • 23/02/2016 at 08:49

      Hi Efrain

      I haven’t used MQX with the SD Card but I agree those errors do not look SD card related. I don’t know of any great tips to test other than to at least perform a read or write to disk. When I was trouble shooting all the problems I had to get this to work I found that almost any slight wrong setting would cause the FatFs libray to cause hard faults. Checking to see if the SD card is inserted is not enough of a test, you actually need to perform a read or write to see if everything is configured correctly. Quite often code will compile fine but if you misconfigured something even slightly you will most likely end up with a hard fault. The only exception weather the card correctly geared up to 50 MHz but this is a lot harder to test. I stepped through what the FatFs and sd card library was doing when it was initialising and saw how it geared up and discovered that the core clock must have a clock speed faster than 50 Mhz for it to gear up correctly.

    • Daniel Caetano
      10/10/2016 at 16:02

      Hi Efrain,

      I’m also trying to implement this in KSDK 1.3 and while everything seems fine nothing is written to the SD card. Did you manage to go succeed with your implementation? If so, do you mind sharing what you found?
      Thank you.

  13. Daniel Caetano
    12/10/2016 at 13:18

    Hello,

    I adapted this example to run on a TWR K64F and I managed to make it run just fine.
    The only problem is that I cannot see the file it wrote when I plug the SD card into a PC. The other way around, if I create a file on the SD card when it’s plugged to a PC, the TWR will not recognize such file.
    Also, when I do a full format to the card on the PC, the TWR will still find the file with the same size as before, but all data inside the file will be erased.
    Do you have any ideas on what could be happening and how to solve it? Thank you.

    • 12/10/2016 at 13:43

      Hi Daniel.

      How are you formatting the SD card. You need to make sure the File system type is FAT12, FAT16, FAT32(r0.0) or exFAT(r1.0). I recommend formatting it as FAT32. FatFs only supports FAT12, FAT16, FAT32(r0.0) or exFAT(r1.0).

      • Daniel Caetano
        12/10/2016 at 13:50

        I’m using Windows8 and I formatted as FAT16 (Windows just calls it FAT).
        Also, I forgot to mention I’m using KSDK 1.3 fatfs and PEx components, although I couldn’t find any relevant changes that could cause this. Any ideas?

      • 12/10/2016 at 14:52

        I have not had this problem myself with KSDK 1.3. I’m wondering if perhaps the SD card has multiple partitions on it. Are you able to check this in Disk Management in Windows. I think in Windows 8 you can get to Disk Management tool by click start menu, Computer Management, then in Computer Management there is a sub tool called Disk Management. From there you should be able to see all the partitions on the SD card.

        Another option is trying to format the SD card with a better SD card formatting tool. One I use that is well known and good is SD Card Formatter: https://www.sdcard.org/downloads/formatter_4/
        When using the SD Card Formatter tool, make sure you go into options and select “FORMAT SIZE ADJUSTMENT” set to “ON”, this will format to the full size of the card and remove the multiple partitions.

      • Daniel Caetano
        12/10/2016 at 15:03

        UPDATE: Finally got it to work. I forced a write on the allocation table so Windows would recognize it as “corrupted”, formatted again as FAT32 and it seems to work now. Thank you.

  14. Fabrizio
    16/12/2016 at 15:48

    Hi, the example using KSDK 1.20 work perfectly on my K64 FRDM.

    I’d like to implement the SD card into another project running the Processor Expert that wasn’t created using the KSDK 1.20.

    The procedure in this article work for me only using the KSDK.

    Is it possible to use the SDCARD into a new project using PEx?

    I’ve also tryed with the components from mcuOnEclipse but i get compilation errors for missing library.

    • 16/12/2016 at 16:35

      Basically if you are able to understand what PINs are used and their muxing and clocking and how to set these values accordingly using those libraries then it should work. Unfortunately I can’t give details on those libraries as I have never used them myself. the mcuOnEclipse library is usually pretty good as they similar but usually simpler to use than the standard Processor Expert. The steps I outline in my guide should work for other boards as long as its not a SPI based SD card and you will need to know the PINS and clock settings for the specific board.

  15. Utsavi
    23/02/2017 at 08:41

    Hi,

    I am using TWR-K60D100M. I create a project by following your steps.

    Project created Successfully without any error, but when I debug the project, I can see that debug stop at f_mount();

    Below are the changes I made for TWR-K60D100M sdcard setting.

    1. GPIO->Input->SDHC_CD_SW(Select PTE-28 for SDCard Detection)
    2. fsl_sdhc1:fsl_sdhc ->pins (Selected as per my twr-k60d100m) also verified with user mannual.

    Which are the settings that I have to do to change from FRDM board to TWR-K60D100M?

    Following are the doubts while following the your steps.

    1. In fsl_sdhc1:fsl_sdhc -> Config-> Transfer mode->ADMA2 is selected by me.
    2. In PORTE:Init_port->Device->PORTE and in muc control->SDHC0_D1 is selected by me.
    3. In clockMan1:fsl_clock_manager -> MCG Setting, I selected PEE.

    Is these all settings are ok?

    If settings are notok then suggest me the correct settings.

  16. Mauro
    25/05/2017 at 18:09

    Thanks, very good job !

    I have successfully integrated it in my project (using SDK 1.3 and Processor Expert)

    Just a suggestion: in my opinion it should be more emphasized the setup for the SHDC pins, it is easy to overlook it and maybe modify only the first of the six pins.

    And a small correction regarding the SDCARD detection: in the function gpio1_PORTE_IRQHandler()
    the line if(PORT_HAL_GetPortIntFlag(PORTE_BASE_PTR) == (1<<SD_CARD_DETECT))
    should change to
    if(PORT_HAL_GetPortIntFlag(PORTE_BASE_PTR) == (1<<GPIO_EXTRACT_PIN(SD_CARD_DETECT)))
    In order to compare the correct value and let the interrupt do its work

  17. Neil
    04/08/2017 at 21:25

    Hi Centaurian,

    Is it possible to have the fsl_sd_disk and the fsl_usb_disk working simultaneously?
    I have an SD card and an USB stick in the board and will like to open files in one, but
    write to the other.

    Thank you,
    Neil

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: