본문 바로가기
임베디드 개발/TMS320F2838x (C28x)

TMS320F28388D ] SD카드 읽기/쓰기

by eteo 2022. 11. 24.

 

// FILE:   sd_fat32.c
//
// TITLE:  SD FATFS Library Example
//
//! \addtogroup driver_example_list
//! <h1> SD FATFS Library Example </h1>
//!
//! This example demonstrates how to use the FATFS library.
//!
//! \b External \b Connections \n
//!  - Connect the SPI signals identifed in the SysConfig to an SD CARD.
//!
//! \b Watch \b Variables \n
//!  - None.
//!
//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"

#include <sdspi/sdspi.h>
#include <sdspi/SDFatFS.h>

uint16_t SDFatFS_config_count = 1;
SDFatFS_Object sdfatfsObject;

SDSPI_Object sdspiObject = {
        .spiHandle = mySDCardSPI_BASE,
        .spiCsGpioIndex = mySDCardCS
};

SDFatFS_Object* SDFatFS_config [] = {&sdfatfsObject};

SDSPI_Handle sdspiHandle = &sdspiObject;


/* String conversion macro */
#define STR_(n)             #n
#define STR(n)              STR_(n)

/* Drive number used for FatFs */
#define DRIVE_NUM           0

const char inputfile[] = STR(DRIVE_NUM)":input.txt";
const char outputfile[] = STR(DRIVE_NUM)":output.txt";

const char textarray[] = "hi nima!";
uint8_t buff[2000] = {0,};
unsigned int bytesWritten = 0;
unsigned int bytesRead = 0;

FIL src;
FIL dst;

unsigned int filesize;
FRESULT fresult;

//
// Main
//
void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Board initialization
    //
    Board_init();

    SDFatFS_init();
    SDFatFS_Handle sdFatFs_handle = SDFatFS_open(sdspiHandle, DRIVE_NUM);
    if (sdFatFs_handle == NULL)
    {
        while(1);
    }


    /* Create a new file object for the file copy */
    fresult = f_open(&dst, outputfile, FA_CREATE_ALWAYS|FA_WRITE);
    if (fresult != FR_OK) {
        while(1);
    }


    fresult = f_open(&src, inputfile, FA_OPEN_EXISTING|FA_READ);
    if (fresult != FR_OK) {
        while(1);
    }

    fresult = f_read(&src, buff, 2000, &bytesRead);
    if (fresult != FR_OK) {
        while(1);
    }

    /*  Write to dst file */
    fresult = f_write(&dst, buff, 2000, &bytesWritten);
    if (fresult != FR_OK) {
        while(1);
    }

    fresult = f_sync(&dst);
    if (fresult != FR_OK) {
        while(1);
    }
    /* Get the filesize of the source file */
    filesize = f_size(&dst);

    /* Close outputfile[] */
    fresult = f_close(&dst);
    if (fresult != FR_OK) {
        while(1);
    }

    fresult = f_close(&src);
    if (fresult != FR_OK) {
        while(1);
    }

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;


    SDFatFS_close(sdFatFs_handle);
}


int32_t fatfs_getFatTime(void)
{
    return 0;
}
//
// End File
//

 

 

 

 

 

input.txt 에 있는 내용을 output.txt에 복사해 쓰도록 기본예제를 약간 수정하였다.

 

 

SPICLK는 LSPCLK에서 클락소스를 공급받는데 LSPCLK/4 보다 클 수 없다.

지금 설정은 SYSCLK 가 200MHz, LSPCLK 가 50MHz 이고 SPICLK는 가능한 최대치인 12.5MHz로 설정해 두었다.

 

TI에선 High-Speed Mode라고 해서 SPI클럭을 최대 50MHz로 동작시킬 수 있는 방법이 있긴한데 LSPCLK를 SYSCLK에서 1분주해서 200MHz로 설정한뒤 SPI High-Speed Mode를 enable 했을 때만 가능하다.

 

하지만 SD Card 인터페이스로 High-Speed Mode를 써보려고 하니 문제가 있었다. SD Card는 initialization 과정에서 잠깐 400KHz로 작동해야 한다고하는데 LSPCLK 가 200MHz면 SPIBRR 레지스터를 설정가능한 최대값인 127로 설정해도 400KHz로 분주할 수 가 없다.

 

아무튼 테스트와 속도향상을 위해 라이브러리를 더 분석해봐야할 것 같다.

 

 

 

 

그리고 중간에 SD 카드를 뽑았다가 다시 꽂더라도 인식이 잘 되게 하려면 일단 HW에서 SD 소켓 모듈의 detect pin 과 연결이 되어있어야 하고 SW에서도 처리를 해주어야 한다.