/********************************************* SD Card Access Algorithms Designed by Karl Antle For use in ECE 402 Biomedical System Design Note: A char sector_array[] must be defined in an external main program Initialize with SPI_init() and SD_reset() Read and Write with SD_write(address) and SD_read(address) *********************************************/ #include //These are the bits and pins that represent the SPI comms #define SPIDI 6 // Port B bit 6 (pin7): data in (data from MMC) #define SPIDO 5 // Port B bit 5 (pin6): data out (data to MMC) #define SPICLK 7 // Port B bit 7 (pin8): clock #define SPE 6 //#define MSTR 4 #define SPR1 1 #define SPR0 0 #define SPIF 7 //This is the Cable Select Pin (Slave Select) that either tells //the SD card to ignore or proceess signals #define CS PORTB.4 //External reference to a 512 byte array that is used to read //and write from the SD card extern unsigned char packet_array[]; extern unsigned int page_address, byte_address; //Function prototypes void SPI_init(void); char SPI(char d); char DF_status(void); char DF_ready(void); char DF_clear(void); char DF_set_buffer2(void); char DF_read_buff2(void); char DF_writepacket_buff1(int time, char* datapacket); char DF_finalize_buff1(void); //******************************************************************** // Function definitions //******************************************************************** // initialize the SPI module onboard the Atmel Mega32 void SPI_init(void) { //Set PORTB Tri state buffers (MISO is input all others output) DDRB = 0xBF; //Set SPI control register to MSSP, enable it, and set speed to 4MHz SPCR = 0x50; // SPI Control - 01110000 // SPIE - Interrupt Enable (0) // SPI - Enable (1) // DORD - Data Order (0) - MSB transmitted first // MSTR - Master/Slave (1) - Master // CPOL - Clock Polarity (0) - SCK low when idle // CPHA - Clock Phase (0) - Sample on leading edge // SPI Mode 0 // SPR1 SPR0 - Clock rate - f_osc/4 //Disable SD Card CS = 1; } // send a 8 bit character over SPI char SPI(unsigned char d) { SPDR = d; while(!(SPSR & 128)); return (SPDR); } // get the data flash status register char DF_status(void) { char ans; CS = 0; // Begin operation SPI(0xD7); // ask for data ans = SPI(0x55); // receive data CS = 1; // End operation return ans; } char DF_ready(void) { return (DF_status()&128); } void DF_address(void){ unsigned char c; c = (unsigned char) (page_address >> 6); SPI(c); c = ((unsigned char) (page_address << 2)) & ((unsigned char) (byte_address >> 8)); SPI(c); c = (unsigned) byte_address; SPI(c); } char DF_clear(void){ char c; int i; for (i=0; i<512; i++){ // Make sure DF is ready while (!DF_ready()) {} // Begin operation CS = 0; // op-code SPI(0x50); // Main memory page to Buffer 2 transfer // address c = (unsigned char) (i >> 3); SPI(c); c = ((unsigned char) (page_address << 5)); SPI(c); c = 0; SPI(c); // End Operation CS = 1; } return 1; } char DF_set_buffer2(void) { // Make sure DF is ready while (!DF_ready()) {} // Begin operation CS = 0; // op-code SPI(0x55); // Main memory page to Buffer 2 transfer // address DF_address(); // End Operation CS = 1; return 1; } char DF_read_buff2(void){ unsigned char c; int i; // Make sure DF is ready while (!DF_ready()) {} // Begin operation CS = 0; // op-code SPI(0xD6); // Buffer 2 read in SPI mode 0 // address DF_address(); SPI(c); // additional don't cares // read data for(i=0; i<8; i++) { packet_array[i] = SPI(0x55); } // End Operation CS = 1; return 1; } char DF_read_buff1(void){ unsigned char c; int i; // Make sure DF is ready while (!DF_ready()) {} // Begin operation CS = 0; // op-code SPI(0xD4); // Buffer 1 read in SPI mode 0 // address DF_address(); SPI(c); // additional don't cares // read data for(i=0; i<8; i++) { packet_array[i] = SPI(0x55); } // End Operation CS = 1; return 1; } char DF_writepacket_buff1(int time, char* datapacket){ unsigned char temp_array[5]; int i; unsigned char c; // Copy array for transmission for (i=0; i<6; i++){ temp_array[i] = datapacket[i]; } // Make sure DF is ready while (!DF_ready()) {} // Begin operation CS = 0; // op-code SPI(0x84); // Buffer 1 Write // address DF_address(); // send data SPI(8); SPI((time>>8)); SPI((time<<8)>>8); SPI(temp_array[1]); SPI(temp_array[2]); SPI(temp_array[3]); SPI(temp_array[4]); SPI(temp_array[5]); // End Operation CS = 1; return 1; } char DF_finalize_buff1(void) { unsigned char c; // Make sure DF is ready while (!DF_ready()) {} // Begin operation CS = 0; // op-code SPI(0x83); // Buffer 1 to main page program with built in erase // address DF_address(); // End Operation CS = 1; return 1; }