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
}
}
/*******************************************************************************
*
* 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;
}
/***************************************************************************//**
* @}
******************************************************************************/
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