Difference between revisions of "PIC32MX: Interfacing to a Secure Digital (SD) Flash Card"

From Mech
Jump to navigationJump to search
Line 33: Line 33:
== Code ==
== Code ==


The code used for this project was based upon the companion code to the recommended text ''Programming 32-bit Microcontrollers in C: Exploring the PIC32'' by Lucio di Jasio. The complete text in PDF form can be accessed [http://www.scribd.com/doc/16601628/Programming-32bit-Microcontrollers-in-C here]. The relevant sections for our project were Day 14: Mass Storage and Day 15: File I/O, which can be found on pages 403 and 427 of the text, respectively.
Where possible, make it a single piece of well-commented cut-and-pastable code, or at least make each function that way, so others can easily copy it. Most comments should be in the code itself; outside the code (on the wiki) should only be explanatory comments that are too cumbersome to include in the code.

All the necessary companion files for Days 14 and 15 can be downloaded [[Media:LAB5-SD Card Reader.zip|here]]. This code has been modified slightly for the purposes of our project. One major modification was the exclusion of the LCD screen and accompanying code, which was left out for the sake of simplicity. Our group focused on the Day 14 code, which can be found in the "14 SDMMC" folder. Upon opening the MPLAB Project "SDMMC," the user should see three .c files in the Source Files folder. These include Explore.c, RWTest.c, and SDMMC.c. Under the Header Files folder, should be HardwareProfile.h, HardwareProfileNU32.h, and SDMMC.h. Finally, procdefs.ld should be included under Other Files.

The complete code for RWTest.c is shown below. The rest of the files can be downloaded from the provided link.

<nowiki>/*
** RWTest.c
**
*/
// configuration bit settings, Fcy=72MHz, Fpb=36MHz
#pragma config POSCMOD=XT, FNOSC=PRIPLL
#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1
#pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF

#include <HardwareProfile.h>
#include <explore.h>
#include <SDMMC.h>
#include <plib.h>
#include <fileio.h>

#define START_ADDRESS 10000 // start block address
#define N_BLOCKS 10 // number of blocks
#define B_SIZE 512 // sector/data block size

char data[ B_SIZE];
char buffer[ B_SIZE];

main( void)
{
SYSTEMConfigPerformance(SYS_FREQ);
mInitAllLEDs();
TRISCbits.TRISC1 = 0;

LBA addr;
int i, j, r;

// 1. initializations
initSD(); // init SD/MMC module

// 2. fill the buffer with pattern
for( i=0; i<B_SIZE; i++)
data[i]= i;

// 3. wait for the card to be inserted
while( !getCD()); // check CD switch
Delayms( 100); // wait contacts de-bounce
if ( initMedia()) // init card
{ // if error code returned
goto End;
}
// 4. fill 16 groups of N_BLOCK sectors with data
addr = START_ADDRESS;
for( j=0; j<16; j++)
{
for( i=0; i<N_BLOCKS; i++)
{
if (!writeSECTOR( addr+i*j, data))
{ // writing failed
goto End;
}
} // i
} // j
// 5. verify the contents of each sector written
addr = START_ADDRESS;
for( j=0; j<16; j++)
{
for( i=0; i<N_BLOCKS; i++)
{ // read back one block at a time
if (!readSECTOR( addr+i*j, buffer))
{ // reading failed
goto End;
}
while(1){
mLED_3_On();
}
// verify each block content
if ( memcmp( data, buffer, B_SIZE))
{ // mismatch
goto End;
}
} // i
} // j

// 7. indicate successful execution

End:
// main loop
while( 1);

} // main
</nowiki>

Revision as of 16:10, 15 February 2010

Original Assignment

Do not erase this section!

Your assignment is to create code that will allow the PIC32 to read and write data to a FAT32 SD card. The SD card should be able to be read by a PC after data has been written on it by the PIC32.

Create functions so that it is easy to read, write and initialize the SD card.

Use the example projects in the "Microchip Solutions/USB Device - Mass Storage - SD card data logger" and "Microchip Solutions/USB Device - Mass Storage - SD card reader" folders as a guide.

Use your code to create a folder on the PIC32 and write 1000 bytes of data to a text file in that folder. How long does it take? Make sure the PC can read the file.

Create a folder on the SD card with the PC and place a text file in the folder with 1000 bytes of data. Read the file with the PIC32. How long does it take?

Overview

NOTE: Code contains errors. Use at your own risk. Hardware on circuit diagram and breadboard has been checked for accuracy.


Secure digital cards, or SD cards, are inexpensive and common mass storage devices that can be interfaced with our PIC to provide a larger nonvolatile data storage space. In this lab, we will interface our PIC 32MX460F512L to communicate with a 2GB FAT32 SD card to allow reading and writing of data. We will do so using SPI mode.

Circuit

The SD card holder has 11 pins with only 6 being directly used for communication with our PIC. The SD card will be powered off 3.3V from our PIC, which will come our mini-usb connection. 10K and 1K resistors are added to allow for a voltage drop for each connection. LEDs are added for the Write Protect (WP) and Card Detect (CD) to see if the card is being read properly externally from the PIC. The LEDs turning on signifies that the card is detected and write protect is off.

EB WF BK Circuit diagram.png

We soldered square pin headers onto the SD card holder to allow easy connection to our breadboard. Please see our circuit below for more detail.


Circuit diagram for communicating between a PIC 32MX460F512L to communicate with a 2GB FAT32 SD card.
Circuit diagram for communicating between a PIC 32MX460F512L to communicate with a 2GB FAT32 SD card

Code

The code used for this project was based upon the companion code to the recommended text Programming 32-bit Microcontrollers in C: Exploring the PIC32 by Lucio di Jasio. The complete text in PDF form can be accessed here. The relevant sections for our project were Day 14: Mass Storage and Day 15: File I/O, which can be found on pages 403 and 427 of the text, respectively.

All the necessary companion files for Days 14 and 15 can be downloaded here. This code has been modified slightly for the purposes of our project. One major modification was the exclusion of the LCD screen and accompanying code, which was left out for the sake of simplicity. Our group focused on the Day 14 code, which can be found in the "14 SDMMC" folder. Upon opening the MPLAB Project "SDMMC," the user should see three .c files in the Source Files folder. These include Explore.c, RWTest.c, and SDMMC.c. Under the Header Files folder, should be HardwareProfile.h, HardwareProfileNU32.h, and SDMMC.h. Finally, procdefs.ld should be included under Other Files.

The complete code for RWTest.c is shown below. The rest of the files can be downloaded from the provided link.

/*
**	RWTest.c
**
*/
// configuration bit settings, Fcy=72MHz, Fpb=36MHz
#pragma config POSCMOD=XT, FNOSC=PRIPLL 
#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1
#pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF

#include <HardwareProfile.h>
#include <explore.h>
#include <SDMMC.h>
#include <plib.h>
#include <fileio.h>

#define START_ADDRESS       10000   // start block address
#define N_BLOCKS            10      // number of blocks
#define B_SIZE              512     // sector/data block size

char    data[ B_SIZE];
char  buffer[ B_SIZE];

main( void)
{
	SYSTEMConfigPerformance(SYS_FREQ);
	mInitAllLEDs();
	TRISCbits.TRISC1 = 0;

    LBA addr;
    int i, j, r;

    // 1. initializations
    initSD();		        // init SD/MMC module

    // 2. fill the buffer with pattern
    for( i=0; i<B_SIZE; i++)
        data[i]= i;

    // 3. wait for the card to be inserted
    while( !getCD());       // check CD switch
    Delayms( 100);          // wait contacts de-bounce
    if ( initMedia())       // init card
    {  // if error code returned
        goto End;
    }
   
    // 4. fill 16 groups of N_BLOCK sectors with data 
    addr = START_ADDRESS;
    for( j=0; j<16; j++)
    {
        for( i=0; i<N_BLOCKS; i++)
        {
            if (!writeSECTOR( addr+i*j, data))
            {  // writing failed
                goto End;
            }
        } // i
    } // j
    
    // 5. verify the contents of each sector written  
    addr = START_ADDRESS;
    for( j=0; j<16; j++)
    {
        for( i=0; i<N_BLOCKS; i++)
        {   // read back one block at a time
            if (!readSECTOR( addr+i*j, buffer))
            {   // reading failed
                goto End;
            }
		while(1){
			mLED_3_On();
		}
            // verify each block content
            if ( memcmp( data, buffer, B_SIZE))
            {   // mismatch
                goto End;
            }
        } // i
    } // j

    // 7. indicate successful execution

End:
    // main loop
    while( 1);

} // main