Fat FileSystem

Page: 123 > Showing page 1 of 3
Author
Mhel
Starting Member
  • Total Posts : 75
  • Reward points : 0
  • Joined: 2007/04/04 05:41:35
  • Location: Mtl. QC
  • Status: offline
2007/04/04 05:57:29 (permalink)
0

Fat FileSystem

Hi, first post here, long time watcher.
I'm not sure if this is the right place
to post this...

I'm probably not ready for this since I'm just starting
to learn, but I'm hoping I could get a little nudge from here,
and I'm obsess :)

I'm trying to make  this http://elm-chan.org/fsw/ff/00index_e.html
to work in Pic24hj128gp510 running @40Mips. I'm using TinyFATFS.
I have managed to read/write sectors , read CID, CSD, but I can't
figure out how to make the file system works.
I get RW_Error when I try to make a file/dir.

I basically just wanted to be able to read/write a text files
(maybe edit then write)

maybe there's somebody here who tried it too,
and can give me some insights.

thanks.

P.S. using mplab7.52 c30 student edition, sandisk 256Mb, fat16 formatted



#1

48 Replies Related Threads

    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/04/05 19:36:33 (permalink)
    0
    making some progress, I'm now able to create directories viewed as folders in WinXP.
    no luck yet trying to create text file


    #2
    DarioG
    leaving this planet
    • Total Posts : 53071
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: porcodioland
    • Status: offline
    RE: Fat FileSystem 2007/04/06 01:19:59 (permalink)
    0
    Strange, I'd had said the opposite held true Smile

    Dario Greggio
    --
    how does it feel, never having been loved? as life fades away, day after day, on this planet made of s h i t...

    #3
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/04/06 09:20:59 (permalink)
    0
    I may have spoken to soon:

    what I did was force the disk_write() to return a 0, which make the f_mkdir() works,
    but that doesn't make sense. I'm just learning thru a lot of reading, and I think
    that the trouble lies on this part of disk_write():


    if (count == 1) {    /* Single block write */
        if ((send_cmd(CMD24, sector) == 0)    /* WRITE_BLOCK */
            && xmit_datablock(buff, 0xFE))
            count = 0;
    }


    it doesn't clear count which is what's returned.
    funny thing is, if I do a sector write it gives me FR_NOT_READY response,
    but writes the sector anyway. BTW: THe not ready response is not from this condition
    if (Stat & STA_NOINIT) return RES_NOTRDY;

    the response is from a put_rc() that interpret the return value of disk_write()


    static
    void put_rc (FRESULT rc)
    {
    const char *p;
    static const char str[] =
        "OK\0" "NOT_READY\0" "NO_FILE\0" "FR_NO_PATH\0" "INVALID_NAME\0" "INVALID_DRIVE\0"
        "DENIED\0" "DISK_FULL\0" "RW_ERROR\0" "WRITE_PROTECTED\0" "NOT_ENABLED\0"
        "NO_FILESYSTEM\0" "INVALID_OBJECT\0" "MKFS_ABORTED\0";
    FRESULT i;

    for (p = str, i = 0; i != rc && *p; i++) {
        while(*p++);
    }
    xprintf("\r\nrc=%u FR_%s", (WORD)rc, p);
    }


    here's my mmc driver derived from the samples and others that are recognizable
    might be useful to some...and maybe I get help to really make it works as intendedwink


    #include <p24HJ128GP510.h>
    #include "delay.h"
    #include "diskio.h"

    //extern void prints(char *str);   // prints to lcd
    //extern void cls();               // clear lcd
    //extern void lcd_gotoxy(uint8 x, uint8 y);//goto lcd column / row

    /* MMC/SD command (in SPI) */
    #define CMD0    (0x40+0)    /* GO_IDLE_STATE */
    #define CMD1    (0x40+1)    /* SEND_OP_COND */
    #define CMD8    (0x40+8)    /* SEND_IF_COND */
    #define CMD9    (0x40+9)    /* SEND_CSD */
    #define CMD10    (0x40+10)    /* SEND_CID */
    #define CMD12    (0x40+12)    /* STOP_TRANSMISSION */
    #define CMD16    (0x40+16)    /* SET_BLOCKLEN */
    #define CMD17    (0x40+17)    /* READ_SINGLE_BLOCK */
    #define CMD18    (0x40+18)    /* READ_MULTIPLE_BLOCK */
    #define CMD24    (0x40+24)    /* WRITE_BLOCK */
    #define CMD25    (0x40+25)    /* WRITE_MULTIPLE_BLOCK */
    #define CMD41    (0x40+41)    /* SEND_OP_COND (ACMD) */
    #define CMD55    (0x40+55)    /* APP_CMD */
    #define CMD58    (0x40+58)    /* READ_OCR */

    /* Control signals (Platform dependent) */
    //#define CS _LATA4
    #define SELECT()    LATA &= ~16  /* MMC CS = L */
    #define DESELECT()  LATA |= 16   /* MMC CS = H */
    #define SOCKPORT   PORTA            /* Socket contact port */
    #define SOCKWP     PORTAbits.RA0            /* Write protect switch (PB5) */
    #define SOCKINS    PORTAbits.RA1            /* Card detect switch (PB4) */
    //#define isWriteProtect()  (PORTAbits.RA0 & 0x01)// _RA1            /* Write protect switch (PB5) */
    //#define isCardDetect()    (PORTAbits.RA1 & 0x01)//_RA0            /* Card detect switch (PB4) */
    //#define WPTRIS  TRISAbits.TRISA0
    //#define INTRIS  TRISAbits.TRISA1

    static volatile
    DSTATUS Stat = STA_NOINIT;    /* Disk status */

    static volatile
    BYTE Timer1, Timer2;        /* 100Hz decrement timer */

    static
    BYTE BlkAddr;            /* 0:Byte addressing, 1:Block addressing */

    //void cfgSPI1Master(void);
    //BYTE wp, cd;

    void cfgSpi1Master(void)
    {
    // SPI1CON1 Register Settings
    SPI1CON1bits.DISSCK = 0;    //Internal Serial Clock is Enabled.
    SPI1CON1bits.DISSDO = 0;    //SDOx pin is controlled by the module.
    SPI1CON1bits.SSEN = 0;        //SS pin not used
    SPI1CON1bits.MODE16 = 0;    //Communication is byte-wide (8 bits).
    SPI1CON1bits.SMP = 0;        //Input Data is sampled at the middle of data output time.
    SPI1CON1bits.CKE = 1;        //Serial output data changes on transition from Idle clock state to active clock state
    SPI1CON1bits.CKP = 0;        //Idle state for clock is a low level; active state is a high level
    SPI1CON1bits.MSTEN = 1;        //Master Mode Enabled

        SPI1CON1bits.SPRE2=1; //2:1  Fcy=40MHz   312KHz
        SPI1CON1bits.SPRE1=1;
        SPI1CON1bits.SPRE0=0;

        SPI1CON1bits.PPRE1=0; //64:1
        SPI1CON1bits.PPRE0=0;

    // SPI1CON2 Register Settings

    SPI1CON2bits.FRMEN = 0;            // Framed Mode Disabled
    SPI1CON2bits.SPIFSD = 0;        // Frame sync pulse output (master)
    SPI1CON2bits.FRMPOL = 0;        // Frame sync pulse is active-low
    //    SPI1CON2bits.FRMDLY = 0;        // Frame sync pulse precedes first bit clock
    //    SPI1CON2bits.ENHBUF = 0;        // FIFO buffer disabled

    //SPI1STAT Register Settings

    SPI1STATbits.SPISIDL = 0;        //Continue module operation in Idle mode
    SPI1STATbits.BUFELM = 0;        //Buffer Length = 1 Word
    SPI1STATbits.SPIROV    =0;        //No Receive Overflow Has Occurred
    SPI1STATbits.SPIEN = 1;                 //Enable SPI Module


    //Interrupt Controller Settings
    IFS0bits.SPI1IF = 0;            //Clear SPI1 Interrupt Flag
    IEC0bits.SPI1IE = 1;            //Enable SPI1 Interrupt

    }

    /*=============================================================================
    Interrupt Service Routines.
    =============================================================================*/
    void __attribute__((__interrupt__)) _SPI1Interrupt(void)
    {
    IFS0bits.SPI1IF =0;
    }


    /*


    */
    unsigned int SPI1_Read(void)
    {  
    SPI1BUF=0xFF;    //if  SPI1BUF=0x00; as it was in the spi lib it doesn' work
    while(!SPI1STATbits.SPIRBF);
    SPI1STATbits.SPIROV = 0;
    if(SPI1CON1bits.MODE16) {
    return SPI1BUF;
    }else{
    return SPI1BUF&0xff;
    }

    }




    /*


    */
    void SPI1_Write(unsigned int data)
    {
    if(SPI1CON1bits.MODE16) {
    SPI1BUF=data;
    }else{
    SPI1BUF=data&0x00ff;
    }
    while(SPI1STATbits.SPITBF);
    data=SPI1BUF;
    }



    /*-----------------------------------------------------------------------*/
    /* Wait for card ready                                                   */
    /*-----------------------------------------------------------------------*/

    static
    BYTE wait_ready (void)
    {
    BYTE res;


    Timer2 = 50;            /* Wait for ready in timeout of 500ms */
    SPI1_Read();
    do
        res = SPI1_Read();
    while ((res != 0xFF) && Timer2);
    return res;
    }


    /*


    */
    void CloseSPI1(void)
    {
    //SELECT();                /* Wait for card ready */
    //wait_ready();
    //DESELECT();
        //SPI1_Read();
    //Disable the Interrupt bit in the  Interrupt Enable Control Register
    IEC0bits.SPI1IE=0;       

    //Disable the module. All pins controlled by PORT Functions  
    SPI1STATbits.SPIEN=0;  

    //Disable the Interrupt flag bit in the Interrupt Flag Control Register
    IFS0bits.SPI1IF=0;

    //Stat |= STA_NOINIT;        /* Set STA_NOINIT */

    }

    /*-----------------------------------------------------------------------*/
    /* Receive a data packet from MMC                                        */
    /*-----------------------------------------------------------------------*/

    static
    BOOL rcvr_datablock (
    BYTE *buff,            /* Data buffer to store received data */
    uint16 btr            /* Byte count (must be even number) */
    )
    {
    BYTE token;


    Timer1 = 10;
    do {                            /* Wait for data packet in timeout of 100ms */
        token = SPI1_Read();
    } while ((token == 0xFF) && Timer1);
    if(token != 0xFE) return FALSE;    /* If not valid data token, retutn with error */

    do {                            /* Receive the data block into buffer */
        *buff++ = SPI1_Read();
        *buff++ = SPI1_Read();
    } while (btr -= 2);
    SPI1_Read();                        /* Discard CRC */
    SPI1_Read();

    return TRUE;                    /* Return with success */
    }



    /*-----------------------------------------------------------------------*/
    /* Send a data packet to MMC                                             */
    /*-----------------------------------------------------------------------*/

    #if _READONLY == 0
    static
    BOOL xmit_datablock (
    const BYTE *buff,    /* 512 byte data block to be transmitted */
    BYTE token            /* Data/Stop token */
    )
    {
    BYTE resp, wc;


    if (wait_ready() != 0xFF) return FALSE;

    SPI1_Write(token);                    /* Xmit data token */
    if (token != 0xFD) {    /* Is data token */
        wc = 0;
        do {                            /* Xmit the 512 byte data block to MMC */
            SPI1_Write(*buff++);
            SPI1_Write(*buff++);
        } while (--wc);
        SPI1_Write(0xFF);                    /* CRC (Dummy) */
        SPI1_Write(0xFF);
        //resp = SPI1_Read();                /* Reveive data response */
        //if ((resp & 0x1F) != 0x05)[b] [/b]       /* If not accepted, return with error */
        //    return FALSE;
    }

    return TRUE;
    }
    #endif /* _READONLY */


    /*-----------------------------------------------------------------------*/
    /* Send a command packet to MMC                                          */
    /*-----------------------------------------------------------------------*/

    static
    BYTE send_cmd (
    BYTE cmd,        /* Command byte */
    DWORD arg        /* Argument */
    )
    {
    BYTE n, res;


    if (wait_ready() != 0xFF) return 0xFF;

    /* Send command packet */
    SPI1_Write(cmd);                        /* Command */
    SPI1_Write((BYTE)(arg >> 24));        /* Argument[31..24] */
    SPI1_Write((BYTE)(arg >> 16));        /* Argument[23..16] */
    SPI1_Write((BYTE)(arg >> 8));            /* Argument[15..8] */
    SPI1_Write((BYTE)arg);                /* Argument[7..0] */
    n = 0;
    if (cmd == CMD0) n = 0x95;            /* CRC for CMD0(0) */
    if (cmd == CMD8) n = 0x87;            /* CRC for CMD8(0x1AA) */
    SPI1_Write(n);

    /* Receive command response */
    if (cmd == CMD12) SPI1_Read();        /* Skip a stuff byte when stop reading */
    n = 10;                                /* Wait for a valid response in timeout of 10 attempts */
    do
        res = SPI1_Read();
    while ((res & 0x80) && --n);

    return res;            /* Return with the response value */
    }


    /*
    static
    int chk_power(void)
    {
    return (PORTE & 0x80) ? 0 : 1;
    }
    */
    /*-----------------------------------------------------------------------*/
    /* Public Functions                                                      */

    /*-----------------------*/
    /* Initialize Disk Drive */
    /* (Platform dependent)  */
    DSTATUS disk_initialize (
    BYTE drv        /* Physical drive nmuber (0) */
    )
    {
    BYTE n, f, ocr[4];

         DESELECT();            /* CS = H */

       //start with slow clk
       SPI1CON1bits.SPRE2=1; //2:1  Fcy=40MHz DOZE 1:1  312KHz
       SPI1CON1bits.SPRE1=1;
       SPI1CON1bits.SPRE0=0;

       SPI1CON1bits.PPRE1=0; //64:1
       SPI1CON1bits.PPRE0=0;
      
       IFS0bits.SPI1IF = 0;            //Clear SPI1 Interrupt Flag
       SPI1STATbits.SPIROV = 0;        //No Receive Overflow Has Occurred
    IEC0bits.SPI1IE = 1;            //Enable SPI1 Interrupt
       SPI1STATbits.SPIEN = 1;                 //Enable SPI Module




        for (Timer1 = 1; Timer1; );    /* Wait for 10ms */
      
    //Done by SPI1STAT.SPIEN
        //  TRISFbits.TRISF6=0;        //Output RF6/SCK1
         //  TRISFbits.TRISF7=1;        //Input  RF7/SDI1_E
         //  TRISFbits.TRISF8=0;        //Output RF8/SDO1_E
      

        if (drv) return STA_NOINIT;            /* Supports only single drive */
    if (Stat & STA_NODISK) return Stat;    /* No card in the socket */
      
       
    for (n = 10; n; n--)    /* 80 dummy clocks */
    SPI1_Read();

    SELECT();                /* CS = L */

    f = 0;
    if (send_cmd(CMD0, 0) == 1) {            /* Enter Idle state */
        Timer1 = 100;                        /* Initialization timeout of 1000 msec */

        if (send_cmd(CMD8, 0x1AA) == 1) {    /* SDC Ver2+  */
            for (n = 0; n < 4; n++)
                ocr[n] = SPI1_Read();
            if (ocr[2] == 0x01 && ocr[3] == 0xAA) {    /* The card can work at vdd range of 2.7-3.6V */
                do {
                    if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 1UL << 30) == 0)
                        break;
                } while (Timer1);
                if (Timer1 && send_cmd(CMD58, 0) == 0) {    /* Check CCS bit */
                    for (n = 0; n < 4; n++)
                        ocr[n] = SPI1_Read();
                    f = (ocr[0] & 0x40) ? 3 : 1;
                }
            }
        } else {                            /* SDC Ver1 or MMC */
            if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1) f = 4;    /* SDC? */
            do {
                if (!f && send_cmd(CMD1, 0) == 0) break;                                /* for MMC */
                if ( f && send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0) break;    /* for SDC Ver1 */
            } while (Timer1);
            if (Timer1) f = 1;
        }
        if (f == 1 && send_cmd(CMD16, 512) != 0)    /* Select R/W block length */
            f = 0;
    }


    DESELECT();            /* CS = H */
    SPI1_Read();            /* Idle (Release DO) */

    if (f & 1) {        /* Initialization succeded */

        BlkAddr = (f & 2) ? 1 : 0;    /* Get addressing mode */
            Stat &= ~STA_NOINIT;        /* Clear STA_NOINIT */
            //Stat = 0;
    //speed up spi clk
            SPI1CON1bits.SPRE2=1; //1:1  Fcy=40MHz DOZE 1:1  10MHz
            SPI1CON1bits.SPRE1=1;
            SPI1CON1bits.SPRE0=1;

            SPI1CON1bits.PPRE1=1; //4:1
            SPI1CON1bits.PPRE0=0;

            //cls();
            //prints("MMC Initialized\n");
    }
    else
    {
         //cls();
    //prints("Not Found"); //power_off();
    CloseSPI1();
    }

    return Stat;
    }

    /*--------------------*/
    /* Return Disk Status */

    DSTATUS disk_status (
    BYTE drv        /* Physical drive nmuber (0) */
    )
    {
    //if (drv) return STA_NOINIT;        /* Supports only single drive */
    //return Stat;
    return (drv) ? STA_NODISK : Stat;
    }



    /*-----------------------------------------------------------------------*/
    /* Read Sector(s)                                                        */
    /*-----------------------------------------------------------------------*/

    DRESULT disk_read (
    BYTE drv,            /* Physical drive nmuber (0) */
    BYTE *buff,            /* Pointer to the data buffer to store read data */
    DWORD sector,        /* Start sector number (LBA) */
    BYTE count            /* Sector count (1..255) */
    )
    {
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;

    if (!BlkAddr) sector *= 512;    /* Convert to byte address if needed */

    SELECT();            /* CS = L */

    if (count == 1) {    /* Single block read */
        if ((send_cmd(CMD17, sector) == 0)    /* READ_SINGLE_BLOCK */
            && rcvr_datablock(buff, 512))
            count = 0;
    }
    else {                /* Multiple block read */
        if (send_cmd(CMD18, sector) == 0) {    /* READ_MULTIPLE_BLOCK */
            do {
                if (!rcvr_datablock(buff, 512)) break;
                buff += 512;
            } while (--count);
            send_cmd(CMD12, 0);                /* STOP_TRANSMISSION */
        }
    }

    DESELECT();            /* CS = H */
    SPI1_Read();            /* Idle (Release DO) */

    return (count ? RES_ERROR : RES_OK);
    }



    /*-----------------------------------------------------------------------*/
    /* Write Sector(s)                                                       */
    /*-----------------------------------------------------------------------*/

    #if _READONLY == 0
    DRESULT disk_write (
    BYTE drv,            /* Physical drive nmuber (0) */
    const BYTE *buff,    /* Pointer to the data to be written */
    DWORD sector,        /* Start sector number (LBA) */
    BYTE count            /* Sector count (1..255) */
    )
    {
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_PROTECT) return RES_WRPRT;
        if (Stat & STA_NOINIT) return RES_NOTRDY;

    if (!BlkAddr) sector *= 512;    /* Convert to byte address if needed */

    SELECT();            /* CS = L */

    if (count == 1) {    /* Single block write */
        if ((send_cmd(CMD24, sector) == 0)    /* WRITE_BLOCK */
            && xmit_datablock(buff, 0xFE))
            count = 0;
    }
    else{                /* Multiple block write */
        if (send_cmd(CMD25, sector) == 0) {    /* WRITE_MULTIPLE_BLOCK */
            do {
                if (!xmit_datablock(buff, 0xFC)) break;
                buff += 512;
            } while (--count);
            if (!xmit_datablock(0, 0xFD))    /* STOP_TRAN token */
                count = 1;
        }
    }



        DESELECT();            /* CS = H */
    SPI1_Read();            /* Idle (Release DO) */
    return (count ? RES_ERROR : RES_OK);
        //return (count ? RES_OK : RES_ERROR);


    }
    #endif /* _READONLY */




    /*-----------------------------------------------------------------------*/
    /* Miscellaneous Functions                                               */
    /*-----------------------------------------------------------------------*/

    DRESULT disk_ioctl (
    BYTE drv,        /* Physical drive nmuber (0) */
    BYTE ctrl,        /* Control code */
    void *buff        /* Buffer to send/receive control data */
    )
    {
    DRESULT res;
    BYTE n, csd[16];
    WORD csize;


    if (drv) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;

    SELECT();        /* CS = L */

    res = RES_ERROR;
    switch (ctrl) {
        case GET_SECTOR_COUNT :    /* Get number of sectors on the disk (DWORD) */
            if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
                n = csd[0] >> 6;
                switch (n) {
                case 0 :    /* CSD ver 1.XX */
                    n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
                    csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
                    *(DWORD*)buff = (DWORD)csize << (n - 9);
                    res = RES_OK;
                    break;
                case 1 :    /* CSD ver 2.00 */
                    csize = csd[9] + ((WORD)csd[8] << 8) + 1;
                    *(DWORD*)buff = (DWORD)csize << 10;
                    res = RES_OK;
                    break;
                }
            }
            break;

        case GET_SECTOR_SIZE :    /* Get sectors on the disk (WORD) */
            *(WORD*)buff = 512;
            res = RES_OK;
            break;

        case CTRL_SYNC :    /* Make sure that data has been written */
            if (wait_ready() == 0xFF)
                res = RES_OK;
            break;

        case MMC_GET_CSD :    /* Receive CSD as a data block (16 bytes) */
            if ((send_cmd(CMD9, 0) == 0)    /* READ_CSD */
                && rcvr_datablock(buff, 16/2))
                res = RES_OK;
            break;

        case MMC_GET_CID :    /* Receive CID as a data block (16 bytes) */
            if ((send_cmd(CMD10, 0) == 0)    /* READ_CID */
                && rcvr_datablock(buff, 16/2))
                res = RES_OK;
            break;

        case MMC_GET_OCR :    /* Receive OCR as an R3 resp (4 bytes) */
            if (send_cmd(CMD58, 0) == 0) {    /* READ_OCR */
                for (n = 0; n < 4; n++)
                    *((BYTE*)buff+n) = SPI1_Read();
                res = RES_OK;
            }
            break;

        default:
            res = RES_PARERR;
    }

    DESELECT();            /* CS = H */
    SPI1_Read();            /* Idle (Release DO) */

    return res;
    }


    /*---------------------------------------*/
    /* Device timer interrupt procedure      */
    /* This must be called in period of 10ms */
    /* (Platform dependent)                  */

    void disk_timerproc (void)
    {
    static BYTE pv;
        BYTE n, s;

    n = Timer1;                        /* 100Hz decrement timer */
    if (n) Timer1 = --n;
    n = Timer2;
    if (n) Timer2 = --n;


    n = pv;
    pv = SOCKPORT & ( SOCKWP |  SOCKINS);    // Sample socket switch

    if (n == pv) {                    // Have contacts stabled?
        s = Stat;


        if (pv & SOCKWP)            // WP is H (write protected)
            s |= STA_PROTECT;
        else                        // WP is L (write enabled)
            s &= ~STA_PROTECT;

        if(pv & SOCKINS)            // INS = H (Socket empty)
           
             s |= (STA_NODISK | STA_NOINIT);
        else                        // INS = L (Card inserted)
            s &= ~STA_NODISK;
                       
        Stat = s;
    }

                 
    }


    EDIT:

    I just change some lines that makes it works for me in case somebody use it.
    post edited by Mhel - 2007/04/11 16:48:38
    #4
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/04/08 05:46:25 (permalink)
    0
    I found the source of the trouble,
    I commented this 3 lines from xmit_datablock():


    //_LATD0 = 1;// LED Debug   
    resp = SPI1_Read();                /* Reveive data response */
        if ((resp & 0x1F) != 0x05)        /* If not accepted, return with error */
            return FALSE;


    I don't know yet the side effects of it, been trying to understand Sandisk's datasheet,
    but it's not sinking very well. Anyhow, I can create dir and files now,
    the best thing is, it's viewable in WinXP too. [8D]



    #5
    proee
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2007/05/02 21:42:15
    • Location: 0
    • Status: offline
    RE: Fat FileSystem 2007/05/02 21:52:41 (permalink)
    0
    Mhel,

    I'm in the process of figuring out how to use this library for simple datalog onto an SD card.  Did you have to write your own Disk IO functions for the PIC?  Also, how stable is your current code, did commenting out those lines seem to work out alright?

    I would like to see a copy of your latest code if it's stable and works.

    thanks,
    Joe

    [8D]
    #6
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/05/03 08:37:13 (permalink)
    0
    the code I posted is the disk IO, it is separate from the fatfs, it's just a combination of what I found here in the forum and the sample files from elm chan's site.
    also there's a nice guy from hungary that had the same problem as I had and have a better fix.
    http://elm-chan.org/bbs/?lang=en&show=4867

    I don't know about the stability of the code since i'm only been playing
    with it for a short while, but before I burnt my the chip [&:] it seems to be working well.
    Besides  I haven't  been able to make it work for my intended purpose.

    come to think of it, maybe i didn't burnt the chip, it could be the limited writes as I have read from the
    other thread.('Just something to consider for the next chip :) )







    #7
    LuVuC
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2007/05/30 04:56:04
    • Location: 0
    • Status: offline
    RE: Fat FileSystem 2007/05/30 05:03:27 (permalink)
    0
    Hi Mhel,

    I'm also having problem creating a map or a file.
    Everything is working so far, except creating a file or a map.

    I think it has to do with the part that makes a directory.
    i.e. I want to create a simple text-file 0:myfile.txt
    0 = drive 0

    Than during singlestepping I see somethin weird going on, and with a special tool on the pc I see a directory with a modified name of my filename.
    I don't know if it sounds familiar to you.

    thnx.
    #8
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/05/30 16:15:47 (permalink)
    0
    I am able to create files now, using the fixed from
    the linked on my post #6.
    this is how I test it:


    FILINFO finfo;
    FATFS fatfs;
    BYTE Buff[512];

    int main(void)
    {
      char tmp;
      uint8 index = 0;
      WORD size, cnt, i, j;
          WORD br, bw;         // File R/W count
          DIR dir;    /* Directory object */
      FATFS *fs;
      FIL file1;        /* File object */

    setup();    //Ports, Pheriperal Configuration

    (WORD) disk_initialize(0); //initialized MMC/SPI

    memset(Buff,0,sizeof(Buff));//clear buffer

    for(i = 0; i<sizeof(Buff); i++)
    {
      Buff[i] = 'x';                              //fill Buff with bunch of x's
    }

    put_rc(f_mount(0, &fatfs));                         /*mount logical drive*/
    put_rc(disk_write(0,Buff,400,1));                   //raw write a bunch of x's to sector 400
    put_rc(f_open(&file1, "tfile1.txt", FA_CREATE_NEW | FA_READ |FA_WRITE )); //create a file
    put_rc(f_write(&file1,Buff,sizeof(Buff),&bw));      //write the content of Buff to created filename
    f_close(&file1);                                    //close file
    //f_mount(0,NULL);                                    //unmount drive//edit this is not suppose to be here

    memset(Buff,0,sizeof(Buff));                        //clear buffer

    //put_rc(f_readdir(&dir, &finfo));
    put_rc( f_open(&file1, "filetest.txt", FA_OPEN_EXISTING | FA_READ));//open existing file
    //put_rc( f_stat("filetest.txt", &finfo));

    size = finfo.fsize;                                 //read the size of file

    for(j=1; j<size ; j++)
    {
    f_read(&file1, &tmp, 1, &cnt);                    //read 1 char at time until EOF

          switch(tmp){
            //LF/CR
            case 0x0D :  xprintf("%s\r", Buff);         //dump the content of buff on LCD
                         memset(Buff,0,sizeof(Buff));   //clear buffer
                         index = 0;                     //reset index
                         Delay_Ms(100);                 //slow down a bit to see file scroll
                         break;
            default   :  Buff[index] = tmp;             //fill buffer 1 char at a time
                         index++; break;
     
      }

    }

    f_close(&file1);
    f_mount(0,NULL);

    }


    I attached my diskio driver as I have been clutterring this thread :)

    EDIT:

    I re-upload the real working one...had trouble with writing file.
    post edited by Mhel - 2007/06/02 17:48:51
    #9
    LuVuC
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2007/05/30 04:56:04
    • Location: 0
    • Status: offline
    RE: Fat FileSystem 2007/05/31 00:28:33 (permalink)
    0
    But if you just use :

    FILINFO finfo;
    FATFS fatfs;
    BYTE Buff[512];

    int main(void)
    {
    char tmp;
    uint8 index = 0;
    WORD size, cnt, i, j;
         WORD br, bw;         // File R/W count
         DIR dir;    /* Directory object */
    FATFS *fs;
    FIL file1;        /* File object */

    setup();    //Ports, Pheriperal Configuration

    (WORD) disk_initialize(0); //initialized MMC/SPI

    memset(Buff,0,sizeof(Buff));//clear buffer

    for(i = 0; i<sizeof(Buff); i++)
    {
    Buff[i] = 'x';                              //fill Buff with bunch of x's
    }

    put_rc(f_mount(0, &fatfs));                         /*mount logical drive*/
    put_rc(disk_write(0,Buff,400,1));                   //raw write a bunch of x's to sector 400
    put_rc(f_open(&file1, "tfile1.txt", FA_CREATE_NEW | FA_READ |FA_WRITE )); //create a file
    put_rc(f_write(&file1,Buff,sizeof(Buff),&bw));      //write the content of Buff to created filename

    Than this will create a file too right?
    I've done something like this:

    int main()
    {
    volatile unsigned char SD = 0;
    FATFS Fs;
    FIL FileObject;
    const char* FileName = "0:TextFile.txt";

    // This function mounts to the storagedevice (i.e. SD card)
    if( f_mount(SD, &Fs) != FR_OK )
       return 0;


    // This function is to create a new file
    if(f_open(&FileObject, FileName, FA_CREATE_NEW|FA_WRITE) != FR_OK)
       return 0;

    char Buffer[] = "Hello Embedded World!";

    WORD ByteToWrite = sizeof(Buffer);
    WORD ByteWritten = 0;
    if(f_write (&FileObject, Buffer, ByteToWrite, &ByteWritten) != FR_OK)
        //than writing a file didn't work.

    return 0;   
    }

    So if somebody has experience with that.
    post edited by LuVuC - 2007/05/31 00:29:38
    #10
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/05/31 13:28:29 (permalink)
    0
    I tried your code I can create the file
    but I can't write in the file. I also
    tried my test same result I don't know what
    happened.

    BTW: filename cant' have "0:" this in front,
    am using TinyFAT.


     int main(void)
    {
    volatile unsigned char SD = 0;
    FATFS Fs;
    FIL FileObject;
     
     char* FileName = "TextFile.txt";

    setup();
    xputs("MMC TEST\n");

    (WORD) disk_initialize(0); //initialized MMC/SPI

     // This function mounts to the storagedevice (i.e. SD card)
    if( f_mount(SD, &Fs) != FR_OK )
       xputs("mounting failed");

     // This function is to create a new file
    if(f_open(&FileObject, FileName, FA_CREATE_NEW | FA_WRITE) != FR_OK)
    xputs("F_OPEN Failed");

    char Buffer[] = "Hello Embedded World!";
     
     WORD ByteToWrite = sizeof(Buffer);
     WORD ByteWritten = 0;
     
    if(f_write (&FileObject, Buffer, ByteToWrite, &ByteWritten) != FR_OK)
       //than writing a file didn't work.
    xputs("F_WRITE Failed");

    xputs("\nDONE");
    while(1);

    return 0; 
    }



    if you find what's wrong pls. post.

    #11
    LuVuC
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2007/05/30 04:56:04
    • Location: 0
    • Status: offline
    RE: Fat FileSystem 2007/06/01 02:07:13 (permalink)
    0
    Hello Mhel,

    I'm using FatFS (the bigger brother of tinyFatFS).
    By the way, I'm another type of microcontroller: Atmel's AT91SAM7A3 ARM7 based microcontroller.
    But that shouldn't make a big difference. The only difference is the use of 32-bits data instead of 8-bits.
    So I did modify in Chan's FatFS source to solve some issue's about bytes and integeres handlings.

    But I will post the solution here. It's a bit frustrating, because I'm about a week trying to solve this problem.
    I even dig out the whole FAT concept to understand Chan's source and maybe find out what went wrong.

    I don't know if you studied Chan's code, but when I singlestep through it seems to try to make a directory first.
    So if I have a file MyFile.txt and want to create it, somehow it tries to make first a directory in this way: MYFILE  TXT
    And if I look into SD card, I see (I don't know which sector) M...L...T.. well, that should be MYFILE  TXT. Why there are some lettres missing is more a problem of the 32-bits issue, so I know what I need to fix. But still, I can't write a file just because it doesn't call writefile function.

    if (fp->flag & FA__DIRTY) {        /* Flush file I/O buffer if needed */
                    if (disk_write(fs->drive, fp->buffer, fp->curr_sect, 1) != RES_OK)
                        goto fw_error;
                    fp->flag &= ~FA__DIRTY;
                }
                fp->curr_sect = sect;            /* Update current sector */
                cc = btw / S_SIZ;            /* When left bytes >= S_SIZ, */
                if (cc) {                /* Write maximum contiguous sectors directly */
                    if (cc > fp->sect_clust)
                                      cc = fp->sect_clust;
                                   
                    if (disk_write(fs->drive, wbuff, sect, cc) != RES_OK)
                        goto fw_error;
                    fp->sect_clust -= cc - 1;
                    fp->curr_sect += cc - 1;
                    wcnt = cc * S_SIZ; continue;

    In this part of the source in ff.c should do the writing to file. But the result of (fp->flag & FA__DIRTY) is zero. So it steps over the
    disk_write(fs->drive, fp->buffer, fp->curr_sect, 1) function and thus it doesn't write at all. And I don't know why.
    #12
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/06/01 08:14:54 (permalink)
    0
    I'm now using FatFS and to the same effect,
    I can only create the file but not write to it.

    In this part of the source in ff.c should do the writing to file. But the result of (fp->flag & FA__DIRTY) is zero. So it steps over the
    disk_write(fs->drive, fp->buffer, fp->curr_sect, 1) function and thus it doesn't write at all. And I don't know why.


    I think your were right on this I tried every combination of
    the "flag & FA__DIRTY" (ff.h, /* File access control and file status flags (FIL.flag) */)
    it will always be 0 no matter what, well unless the status flag is FA__DIRTY
    which I think would be the same as this  (fp->flag == FA__DIRTY)

    you might be interested to know that I have tried again
    as per my post #4, and I was able to create the file and write to it.
    (I was almost sure that I had it fixed)

    I have only skim through Chan's lib,
    at my current knowledge of programming
    the information in it is overwhelming.
    I'm sorry to say that my understanding
    of the internal workings of the FATFS lib is
    at the lower end.
    #13
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/06/01 10:09:30 (permalink)
    0
    I may have gotten the right fix,
    I just added an extra  SPI1_Write(0xFF);
    after the dummy crc in xmit_datablock
    function, and now I can write in the file.
    I got it from other mmc driver I have
    gathered.
    #14
    LuVuC
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2007/05/30 04:56:04
    • Location: 0
    • Status: offline
    RE: Fat FileSystem 2007/06/04 03:25:40 (permalink)
    0
    I think I know what the problem is.
    Problem is reading or writing een array of bytes.
    If I want to write from 32 bits unsigned int into an byte array of x elements than this is what happened.
    e.g.

    unsigned int iVal = 0x12345678;
    unsigned BYTE a[512];

    a[0] = iVal;

    //This results in:
    a[0] = 0x12;
    a[1] = 0x00;      //this should be 0x34
    a[2] = 0x00;      //this should be 0x56
    a[3] = 0x00;      //this should be 0x78

    So I've solved it in some functions,
    but appearently there are more functions used which need to be modified too.

    I hope I get this sovled soon.
    post edited by LuVuC - 2007/06/04 03:28:03
    #15
    LuVuC
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2007/05/30 04:56:04
    • Location: 0
    • Status: offline
    RE: Fat FileSystem 2007/06/04 07:37:49 (permalink)
    0
    Hello Mhel!!
    I got it working!! Well, I mean it creates a file, the new problem is the content is empty hahahaha.
    At least I found the cause of the problem. It's a bit painfull that I didn't came up earlier with the solution.
    Cause I already suspected the cause, but I thaught I fixed it already, so I didn't look to that part of code.

    The problem is as follows. In the writefunction, I need to put 4 bytes in one 32-bits sendregister.
    Because of 32-bits vs. 8-bits data-handling the register is just filled with the first byte of the total four and the
    rest of the three bytes was set to zero. So three bytes of data is lost, which makes the whole writing corrupt.

    Pffff damn, sometimes I have to learn important lessons on the hard way.

    So I made a .txt and .wav files and Windows shows it like I've dreamt about it hahaha.
    Now I only have to find out why I can't see the content.

    If you know that, than I like to know.

    I hope my comments will help others.
    #16
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    RE: Fat FileSystem 2007/06/04 13:04:10 (permalink)
    0
    good  to hear it's working!
    I just realized you're in the 32bits realm :)
    before I added my fix, I had the same trouble
    I was able to create the file but not write in it,
    but it's ok now.

    I'm actually trying to read/write a .ini file now
    I found a source which I thought I could make
    work, I'm currently fighting with it,  it appear
    that it should work but no go. I was thinking
    of using eeprom, but I have no knowledge of
    eeprom yet, and I read that it would be difficult to
    do something like the workings of an ini file.




    #17
    LuVuC
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2007/05/30 04:56:04
    • Location: 0
    • Status: offline
    RE: Fat FileSystem 2007/06/05 02:18:23 (permalink)
    0
    Hi Mhel,

    Thank you for your enthousiastic reply Smile
    Reading a ini-file should work, I think you just need check an ini-file byte by byte,
    how it is composed. Maybe there is some kind of a header in it.

    Reading from an EEPROM sounds like a nice challenge to get it work.
    Moslty EEPROM are used to store some settings, different languages for a menu etc...
    Also measurements which are meuasured over a long time periodes, like every minute or something.
    But writing the content of a file you do that directly, or you call the write-function of FatFS?
    #18
    Mhel
    Starting Member
    • Total Posts : 75
    • Reward points : 0
    • Joined: 2007/04/04 05:41:35
    • Location: Mtl. QC
    • Status: offline
    parsing .ini 2007/06/05 13:32:17 (permalink)
    0
    I test the file write like this.


    f_open(&tst, "test.ini", FA_OPEN_ALWAYS | FA_WRITE))); //create the file


    //write to the file
    put_rc((res = f_write(&tst, "[Header 1]\n", strlen("[Header 1]\n"), &bw))) ;
    put_rc((res = f_write(&tst, "[Header 2]\n", strlen("[Header 2]\n"), &bw))) ;
    put_rc((res = f_write(&tst, "[Header 3]\n", strlen("[Header 3]\n"), &bw))) ;
    put_rc((res = f_write(&tst, "[Header 4]\n", strlen("[Header 4]\n"), &bw))) ;
    put_rc((res = f_write(&tst, "[Header 5]\n", strlen("[Header 5]\n"), &bw))) ;
    put_rc((res = f_write(&tst, "[Header 6]\n", strlen("[Header 6]\n"), &bw))) ;
    f_close(&tst);


    I can view the content of the "test.ini"file if I write it like the above code,
    but the parser I'm trying to understand uses fprintf

    so I got this from one of the threads here,
    I conjured it up to use the FatFS write function...


    int f_fprintf(FIL *fp, const char *fmt, ... )
    {
        va_list argptr;
        int len = 1;
        char str[BUFFERSIZE];
        WORD ByteWritten;

        memset(&str, 0x00, sizeof(str) );

        va_start(argptr, fmt);
        len = vsprintf(str, fmt, argptr);
        va_end(argptr);

        f_write(fp, str, sizeof(str), &ByteWritten);

        return len;
    }


    ...but it doesn't work properly, I attached a test.ini
    if opened in notepad, you could see something was written
    but if I open in ConTEXT editor, I only see one line.
    If somebody could tell me what's wrong, would be appreciated.

    (had to rename attached doesnt take .ini)
    #19
    Luca Pascarella
    Starting Member
    • Total Posts : 31
    • Reward points : 0
    • Joined: 2007/05/28 00:53:17
    • Location: Italy
    • Status: offline
    RE: parsing .ini 2007/06/05 23:47:37 (permalink)
    0
    Hi,  
     
    also I use the library ff.h, I have used her with the series 18F (on the PIC18F4620) and it worked to wonder, few days ago I have implemented her on the series 24HJ (on the PIC24HJ256GP206) and it is not all right.
    As first problem in writing creates me the empty file. 
    How second problem is the selection _MCU_ENDIAN with the series 18 I succeeded in making to go it with the "word access" with an improvement of the code with the series 24 have to necessarily put the selection to "byte-by-byte access" otherwise the pic him reset before beginning the opening of the file, doesn't succeed in understanding the why since the 24 is to 16bit.

    You as you hold planned _MCU_ENDIAN?

    I use a library of "diskio.h" a few different from that shown from Mhel but is essentially identical.

    Aspect your opinions kindest regards.
    #20
    Page: 123 > Showing page 1 of 3
    Jump to:
    © 2017 APG vNext Commercial Version 4.5