This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/MSP430F5529: MSP430F5529 SD Card interface with FATFS

Part Number: MSP430F5529
Other Parts Discussed in Thread: ENERGIA

Tool/software: TI C/C++ Compiler

Hello, Ti community,

Currently, I'm trying to interface fat32 sd card with msp430f5529. I got this code from the resolved post in this forum. I having an issue like sometimes code working perfectly and creating the file and storing a data into it sometimes it is not working. I attached my code here and I'm using 2gb sd card.

///*The following code is a stripped down version of a previous project, there
// * may be parts of this code that are unnecessary. This example will create
// * text file and write a few letters. If you have any questions or would like
// * to learn more how to implement this project using more extensive commands
// * please contact me at OCB456@aol.com. Thanks!
// * */
//
//#include <MSP430F5529.h>
//#include "ff.h"
//#include "diskio.h"
//#include "sdmmc.h"
//
//
//
//void main(void)
//{
//    WDTCTL = WDTPW+WDTHOLD;                     // Stop watchdog timer
//    P4SEL |= BIT4+BIT5;             // P3.3,4 = USCI_A0 TXD/RXD
//    UCA1CTL1 |= UCSWRST;            // **Put state machine in reset**
//    UCA1CTL1 |= UCSSEL_2;           // SMCLK
//    UCA1BR0 = 9;                    // 1MHz 115200 (see User's Guide)
//    UCA1BR1 = 0;                    // 1MHz 115200
//    UCA1MCTL |= UCBRS_1 + UCBRF_0;  // Modulation UCBRSx=1, UCBRFx=0
//    UCA1CTL1 &= ~UCSWRST;           // **Initialize USCI state machine**
//    UCA1IE |= UCRXIE;               // Enable USCI_A0 RX interrupt
//
//    __bis_SR_register(GIE);  // interrupts enabled
//    //    char array[] = "birla nesan";
//
//    initCLK();
//    __enable_interrupt();
//
//    fat_init();                                 //mount, set directory to read from, assign file
//
//    unsigned int bytesWritten;
//    int i;
//    char a;
//
//
//    for(i=0; i<100; i++)
//    {
//        f_lseek(&file,i*5 );
//        f_write(&file, "birla", 6, &bytesWritten);
//        __delay_cycles(5000);
//
//    }
//    for(i=0; i<100; i++)
//    {
//        f_lseek(&file,i );
//        f_read(&file,&a,1,&bytesWritten);
//        while (!(UCA1IFG&UCTXIFG));
//        UCA1TXBUF= a; //Write the character at the location specified by the pointer and increment pointer
//
//
//    }
//
//    f_close(&file);
//    f_mount(0,0);
//
//
//    while(1);
//}
























#include <MSP430F5529.h>
#include "ff.h"
#include "diskio.h"

void initCLK(void);
void SetVcoreUp (unsigned int level);
FRESULT WriteFile(char*, char*, WORD);
void fat_init(void);

FIL file;                                               /* Opened file object */
FATFS fatfs;                                            /* File system object */
DIRS dir;                                               /* Directory object   */
DIRS dir2;
FRESULT errCode;                                        /* Error code object  */
FRESULT res;                                            /* Result object      */
UINT bytesRead;                                         /* Bytes read object  */
UINT read;                                              /* Read bytes object  */


FATFS test_for_new; // to check if a new file can be written
FIL test_file;

unsigned char MST_Data,SLV_Data;
BYTE buffer[32];
int result=1;

void main(void){

    WDTCTL = WDTPW+WDTHOLD;                     // Stop watchdog timer

    initCLK();

    __enable_interrupt();



    fat_init();                                 //mount, set directory to read from, assign file
    unsigned int bytesWritten;
    f_write(&file, "abcdefg \r\n", 32, &bytesWritten);
    f_write(&file, "ok", 32, &bytesWritten);
    f_close(&file);
//    f_closedir(&dir);
    f_mount(0,0);


   /* f_mount(0,&test_for_new); // f_mount(0,0);
    //new
    f_open(&test_file, "test_file.txt", FA_CREATE_NEW);
    f_write(&test_file, "Hi Mom", 32, &bytesWritten);
    f_close(&test_file);//new*/
 //   f_closedir(&dir2);
  //  f_mount(0,&test_for_new);
    while(1);
}

void fat_init(void){
    errCode = -1;

    while (errCode != FR_OK){                               //go until f_open returns FR_OK (function successful)
        errCode = f_mount(0, &fatfs);                       //mount drive number 0
        errCode = f_opendir(&dir, "/");                     //root directory

        errCode = f_open(&file, "TESTE.txt", FA_CREATE_ALWAYS | FA_WRITE);
        if(errCode != FR_OK)
            result=0;                                       //used as a debugging flag
    }
}


void initCLK(void){
  volatile unsigned int i;

  // Increase Vcore setting to level3 to support fsystem=25MHz
  // NOTE: Change core voltage one level at a time..
  SetVcoreUp (0x01);
  SetVcoreUp (0x02);
  SetVcoreUp (0x03);

  UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO
  UCSCTL4 |= SELA_2;                        // Set ACLK = REFO

  __bis_SR_register(SCG0);                  // Disable the FLL control loop
  UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  UCSCTL1 = DCORSEL_7;                      // Select DCO range 50MHz operation
  UCSCTL2 = FLLD_1 + 762;                   // Set DCO Multiplier for 25MHz
                                            // (N + 1) * FLLRef = Fdco
                                            // (762 + 1) * 32768 = 25MHz
                                            // Set FLL Div = fDCOCLK/2
  __bic_SR_register(SCG0);                  // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle
  __delay_cycles(782000);

  // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
}

void SetVcoreUp (unsigned int level)
{
  // Open PMM registers for write
  PMMCTL0_H = PMMPW_H;
  // Set SVS/SVM high side new level
  SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
  // Set SVM low side to new level
  SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
  // Wait till SVM is settled
  while ((PMMIFG & SVSMLDLYIFG) == 0);
  // Clear already set flags
  PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
  // Set VCore to new level
  PMMCTL0_L = PMMCOREV0 * level;
  // Wait till new level reached
  if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
  // Set SVS/SVM low side to new level
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
  // Lock PMM registers for write access
  PMMCTL0_H = 0x00;
}
/*
 * sdmmc.cpp
 *
 *  Created on: Sep 20, 2015
 *      Author: Engineeridea
 */
#include <msp430.h>
#include "C:\Users\Birla\Desktop\Temp logger\sd_card\sdmmc.h"

void SetVcoreUp (unsigned int level)
{
  // Open PMM registers for write
  PMMCTL0_H = PMMPW_H;
  // Set SVS/SVM high side new level
  SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
  // Set SVM low side to new level
  SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
  // Wait till SVM is settled
  while ((PMMIFG & SVSMLDLYIFG) == 0);
  // Clear already set flags
  PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
  // Set VCore to new level
  PMMCTL0_L = PMMCOREV0 * level;
  // Wait till new level reached
  if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
  // Set SVS/SVM low side to new level
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
  // Lock PMM registers for write access
  PMMCTL0_H = 0x00;
}

void initCLK(void){
/* MCLK = 4 MHZ XT2 Crystal */

  volatile unsigned int i;

  P2DIR |= BIT2;                            // SMCLK set out to pins
  P2SEL |= BIT2;
  P7DIR |= BIT7;                            // MCLK set out to pins
  P7SEL |= BIT7;

  P5SEL |= BIT2+BIT3;                       // Port select XT2
  P5SEL |= BIT4+BIT5;                       // Port select XT1

  UCSCTL6 &= ~XT2OFF;                       // Set XT2 On
  UCSCTL6 &= ~XT1OFF;                       // Set XT1 On

  // Increase Vcore setting to level3 to support fsystem=25MHz
  // NOTE: Change core voltage one level at a time..
  SetVcoreUp (0x01);
  SetVcoreUp (0x02);
  SetVcoreUp (0x03);

  UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO
  UCSCTL4 |= SELA_2;                        // Set ACLK = REFO

  //__bis_SR_register(SCG0);                  // Disable the FLL control loop
  //UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  //UCSCTL1 = DCORSEL_7;                      // Select DCO range 50MHz operation
  //UCSCTL2 = FLLD_1 + 762;                   // Set DCO Multiplier for 25MHz
                                            // (N + 1) * FLLRef = Fdco
                                            // (762 + 1) * 32768 = 25MHz
                                            // Set FLL Div = fDCOCLK/2
  __bic_SR_register(SCG0);                  // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle
  __delay_cycles(782000);

  // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

  UCSCTL6 &= ~XT2DRIVE0;                    				// Decrease XT2 Drive according to expected frequency
  UCSCTL4 |= SELA__XT1CLK + SELS__XT2CLK | SELM__XT2CLK;    // Select SMCLK, ACLK source and MCLK source
}

void fat_init(void)
{
    errCode = FR_NAN;

    while (errCode != FR_OK){                               //go until f_open returns FR_OK (function successful)
        errCode = f_mount(0, &fatfs);                       //mount drive number 0
        errCode = f_opendir(&dir, "/");				    	//root directory

        errCode = f_open(&file, "/teste.txt", FA_CREATE_ALWAYS | FA_WRITE);
        //if(errCode != FR_OK)
            //result=0;                                       //used as a debugging flag
    }
}
sdmmc.h2746.diskio.h2746.diskio.hff.cff.hffconf.hHAL_SDCard.h
/*******************************************************************************
 *
 *  HAL_SDCard.c - Driver for the SD Card slot
 *
 *  Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************/

/***************************************************************************//**
 * @file       HAL_SDCard.c
 * @addtogroup HAL_SDCard
 * @{
 ******************************************************************************/
#include "msp430.h"
#include "C:\Users\Birla\Desktop\Temp logger\sd_card\sdcard\HAL_SDCard.h"

// Pins from MSP430 connected to the SD Card
#define SPI_SIMO        BIT0  // 0x0001
#define SPI_SOMI        BIT1  // 0x0002
#define SPI_CLK         BIT2  // 0x0004
#define SD_CS           BIT7  // 0x0020

// Ports
#define SPI_SEL         P3SEL
#define SPI_DIR         P3DIR
#define SPI_OUT         P3OUT
#define SPI_REN         P3REN
#define SD_CS_SEL       P2SEL
#define SD_CS_OUT       P2OUT
#define SD_CS_DIR       P2DIR

/***************************************************************************//**
 * @brief   Initialize SD Card
 * @param   None
 * @return  None
 ******************************************************************************/

void SDCard_init(void)
{
    //*
    // Port initialization for SD Card operation
    SPI_SEL |= SPI_CLK + SPI_SOMI + SPI_SIMO;              //Set P3.0-2 to peripherals
    SPI_DIR |= SPI_CLK + SPI_SIMO;                         //THIS MIGHT BE UNNECESSARY****
    SPI_REN |= SPI_SOMI;                                   // Pull-Ups on SD Card SOMI
    SPI_OUT |= SPI_SOMI;                                   // Certain SD Card Brands need pull-ups

    SD_CS_SEL &= ~SD_CS;
    SD_CS_OUT |= SD_CS;
    SD_CS_DIR |= SD_CS;

    // Initialize USCI_B1 for SPI Master operation
    UCB0CTL1 |= UCSWRST;                                   // Put state machine in reset
    UCB0CTL0 = UCCKPL + UCMSB + UCMST + UCMODE_0 + UCSYNC; // 3-pin, 8-bit SPI master
    // Clock polarity select - The inactive state is high
    // MSB first
    UCB0CTL1 = UCSWRST + UCSSEL_2;                         // Use SMCLK, keep RESET
    UCB0BR0 = 63;                                          // Initial SPI clock must be <400kHz
    UCB0BR1 = 0;                                           // f_UCxCLK = 25MHz/63 = 397kHz
    UCB0CTL1 &= ~UCSWRST;                                  // Release USCI state machine
    UCB0IFG &= ~UCRXIFG;
}

/***************************************************************************//**
 * @brief   Enable fast SD Card SPI transfers. This function is typically
 *          called after the initial SD Card setup is done to maximize
 *          transfer speed.
 * @param   None
 * @return  None
 ******************************************************************************/

void SDCard_fastMode(void)
{
    UCB0CTL1 |= UCSWRST;                                   // Put state machine in reset
    UCB0BR0 = 2;                                           // f_UCxCLK = 25MHz/2 = 12.5MHz
    UCB0BR1 = 0;
    UCB0CTL1 &= ~UCSWRST;                                  // Release USCI state machine
}

/***************************************************************************//**
 * @brief   Read a frame of bytes via SPI
 * @param   pBuffer Place to store the received bytes
 * @param   size Indicator of how many bytes to receive
 * @return  None
 ******************************************************************************/

void SDCard_readFrame(uint8_t *pBuffer, uint16_t size)
{
    uint16_t gie = __get_SR_register() & GIE;              // Store current GIE state

    __disable_interrupt();                                 // Make this operation atomic

    UCB0IFG &= ~UCRXIFG;                                   // Ensure RXIFG is clear

    // Clock the actual data transfer and receive the bytes
    while (size--){
        while (!(UCB0IFG & UCTXIFG)) ;                     // Wait while not ready for TX
        UCB0TXBUF = 0xff;                                  // Write dummy byte
        while (!(UCB0IFG & UCRXIFG)) ;                     // Wait for RX buffer (full)
        *pBuffer++ = UCB0RXBUF;
    }

    __bis_SR_register(gie);                                // Restore original GIE state
}

/***************************************************************************//**
 * @brief   Send a frame of bytes via SPI
 * @param   pBuffer Place that holds the bytes to send
 * @param   size Indicator of how many bytes to send
 * @return  None
 ******************************************************************************/

void SDCard_sendFrame(uint8_t *pBuffer, uint16_t size)
{
    uint16_t gie = __get_SR_register() & GIE;              // Store current GIE state

    __disable_interrupt();                                 // Make this operation atomic

    // Clock the actual data transfer and send the bytes. Note that we
    // intentionally not read out the receive buffer during frame transmission
    // in order to optimize transfer speed, however we need to take care of the
    // resulting overrun condition.
    while (size--){
        while (!(UCB0IFG & UCTXIFG)) ;                     // Wait while not ready for TX
        UCB0TXBUF = *pBuffer++;                            // Write byte
    }
    while (UCB0STAT & UCBUSY) ;                            // Wait for all TX/RX to finish

    UCB0RXBUF;                                             // Dummy read to empty RX buffer
                                                           // and clear any overrun conditions

    __bis_SR_register(gie);                                // Restore original GIE state
}

/***************************************************************************//**
 * @brief   Set the SD Card's chip-select signal to high
 * @param   None
 * @return  None
 ******************************************************************************/

void SDCard_setCSHigh(void)
{
    SD_CS_OUT |= SD_CS;
}

/***************************************************************************//**
 * @brief   Set the SD Card's chip-select signal to low
 * @param   None
 * @return  None
 ******************************************************************************/

void SDCard_setCSLow(void)
{
    SD_CS_OUT &= ~SD_CS;
}

/***************************************************************************//**
 * @}
 ******************************************************************************/
mmc.h

And my code exactly hang HAL_sdcard.c here

void SDCard_readFrame(uint8_t *pBuffer, uint16_t size)
{
    uint16_t gie = __get_SR_register() & GIE;              // Store current GIE state

    __disable_interrupt();                                 // Make this operation atomic

    UCB0IFG &= ~UCRXIFG;                                   // Ensure RXIFG is clear

    // Clock the actual data transfer and receive the bytes
    while (size--){
        while (!(UCB0IFG & UCTXIFG)) ;                     // Wait while not ready for TX
        UCB0TXBUF = 0xff;                                  // Write dummy byte
        while (!(UCB0IFG & UCRXIFG)) ;                     // Wait for RX buffer (full)
        *pBuffer++ = UCB0RXBUF;
    }


    __bis_SR_register(gie);                                // Restore original GIE state
}

if anyone solved the issue please help me to solve mine

**Attention** This is a public forum