📄 mmc_datalogger_eeprom.c
字号:
counter++; // Increment byte counter;
while(!SPIF){}
SPIF = 0;
}
SPI0DAT = 0xFF; // Write CRC bytes (don't cares);
while(!SPIF){}
SPIF = 0;
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
do // Read Data Response from card;
{ //
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
data_resp = SPI0DAT;
} // When bit 0 of the MMC response
// is clear, a valid data response
// has been received;
while((data_resp & DATA_RESP_MASK) != 0x01);
do // Wait for end of busy signal;
{
SPI0DAT = 0xFF; // Start SPI transfer to receive
while(!SPIF){} // busy tokens;
SPIF = 0;
}
while(SPI0DAT == 0x00); // When a non-zero token is returned,
// card is no longer busy;
SPI0DAT = 0xFF; // Issue 8 SPI clocks so that all card
while(!SPIF){} // operations can complete;
SPIF = 0;
break;
default: break;
}
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
NSSMD0 = 1; // Deselect memory card;
SPI0DAT = 0xFF; // Send 8 more SPI clocks to ensure
while(!SPIF){} // the card has finished all necessary
SPIF = 0; // operations;
// Restore old block length if needed;
if((current_command.command_byte == 9)||
(current_command.command_byte == 10))
{
current_blklen = old_blklen;
}
return card_response.i;
}
//-----------------------------------------------------------------------------
// MMC_FLASH_Init
//-----------------------------------------------------------------------------
//
// This function initializes the flash card, configures it to operate in SPI
// mode, and reads the operating conditions register to ensure that the device
// has initialized correctly. It also determines the size of the card by
// reading the Card Specific Data Register (CSD).
void MMC_FLASH_Init (void)
{
idata UINT card_status; // Stores card status returned from
// MMC function calls(MMC_Command_Exec);
idata unsigned char counter = 0; // SPI byte counter;
idata unsigned int size; // Stores size variable from card;
unsigned int pchar; // Pointer int EEPROM for storing MMC
// register values;
unsigned char space[4]; // 4 bytes of memory for use in storing
// temporary register values from MMC;
unsigned char *lpchar; // Local storage for data from MMC;
// Transmit at least 64 SPI clocks
// before any bus comm occurs.
pchar = LOCAL_BLOCK;
lpchar = &space[0];
for(counter = 0; counter < 10; counter++)
{
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
}
// Send the GO_IDLE_STATE command with
// CS driven low; This causes the MMC
// to enter SPI mode;
card_status.i = MMC_Command_Exec(GO_IDLE_STATE,EMPTY,EMPTY);
// Send the SEND_OP_COND command
do // until the MMC indicates that it is
{ // no longer busy (ready for commands);
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
card_status.i = MMC_Command_Exec(SEND_OP_COND,EMPTY,EMPTY);
}
while ((card_status.b[0] & 0x01));
SPI0DAT = 0xFF; // Send 8 more SPI clocks to complete
while(!SPIF){} // the initialization sequence;
SPIF = 0;
do // Read the Operating Conditions
{ // Register (OCR);
card_status.i = MMC_Command_Exec(READ_OCR,EMPTY,pchar);
// Get OCR from EEPROM;
EEPROM_ReadArray(lpchar,pchar,4);
}
while(!(*lpchar&0x80)); // Test for card ready;
card_status.i = MMC_Command_Exec(SEND_STATUS,EMPTY,EMPTY);
// Get the Card Specific Data (CSD)
// register to determine the size of the
// MMC;
card_status.i = MMC_Command_Exec(SEND_CSD,EMPTY,pchar);
// Get CSD from EEPROM;
*lpchar = EEPROM_ReadByte(pchar+9);
// Size indicator is in the 9th byte of
// CSD register;
// Extract size indicator bits;
size = (unsigned int)((((*lpchar) & 0x03) << 1) |
(((*(lpchar+1)) & 0x80) >> 7));
switch(size) // Assign PHYSICAL_SIZE variable to
{ // appropriate size constant;
case 1: PHYSICAL_SIZE = PS_8MB; break;
case 2: PHYSICAL_SIZE = PS_16MB; break;
case 3: PHYSICAL_SIZE = PS_32MB; break;
case 4: PHYSICAL_SIZE = PS_64MB; break;
case 5: PHYSICAL_SIZE = PS_128MB; break;
default: break;
}
// Determine the number of MMC sectors;
PHYSICAL_BLOCKS = PHYSICAL_SIZE / PHYSICAL_BLOCK_SIZE;
LOG_SIZE = PHYSICAL_SIZE - LOG_ADDR;
}
//-----------------------------------------------------------------------------
// MMC_FLASH_Read
//-----------------------------------------------------------------------------
//
// This function reads <length> bytes of MMC data from address <address>, and
// stores them in EEPROM space at the location pointed to by <pchar>.
// There are two cases that must be considered when performing a read. If the
// requested data is located entirely in a single FLASH block, the function
// sets the read length appropriately and issues a read command. If requested
// data crosses a FLASH block boundary, the read operation is broken into two
// parts. The first part reads data from the starting address to the end of
// the starting block, and then reads from the start of the next block to the
// end of the requested data. Before each read, the read length must be set
// to the proper value.
unsigned char MMC_FLASH_Read (unsigned long address, unsigned int pchar,
unsigned int length)
{
idata unsigned long flash_page_1; // Stores address of first FLASH page;
idata unsigned long flash_page_2; // Stores address of second FLASH page;
idata unsigned int card_status; // Stores MMC status after each MMC
// command;
if(length > 512) return 0; // Test for valid data length; Length
// must be less than 512 bytes;
// Find address of first FLASH block;
flash_page_1 = address & ~(PHYSICAL_BLOCK_SIZE-1);
// Find address of second FLASH block;
flash_page_2 = (address+length-1) & ~(PHYSICAL_BLOCK_SIZE-1);
if(flash_page_1 == flash_page_2) // Execute the following if data is
{ // located within one FLASH block;
// Set read length to requested data
// length;
card_status = MMC_Command_Exec(SET_BLOCKLEN,(unsigned long)length,
EMPTY);
// Issue read command;
card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,address,pchar);
}
else // Execute the following if data crosses
{ // MMC block boundary;
// Set the read length to the length
// from the starting address to the
// end of the first FLASH page;
card_status = MMC_Command_Exec(SET_BLOCKLEN,
(unsigned long)(flash_page_2 - address),
EMPTY);
// Issue read command;
card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,address,pchar);
// Set read length to the length from
// the start of the second FLASH page
// to the end of the data;
card_status = MMC_Command_Exec(SET_BLOCKLEN,
(unsigned long)length -
(flash_page_2 - address),
EMPTY);
// Issue second read command; Notice
// that the incoming data stored in
// external RAM must be offset from the
// original pointer value by the length
// of data stored during the first read
// operation;
card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_2,
pchar + (flash_page_2 - address));
}
}
//-----------------------------------------------------------------------------
// MMC_FLASH_Write
//-----------------------------------------------------------------------------
//
// This function operates much like the MMC_FLASH_Read function. As
// with the MMC_FLASH_Read function, if the desired write space crosses a FLASH
// block boundary, the operation must be broken into two pieces.
// MMC_FLASH_Write first reads the addressed block of MMC data into the EEPROM,
// then modifies the contents of that block in EEPROM space; Finally, the MMC
// block is erased in the MMC and replaced by the updated block from EEPROM
// space;
//
unsigned char MMC_FLASH_Write (unsigned long address, unsigned int scratch,
unsigned int wdata, unsigned int length)
{
idata unsigned long flash_page_1; // First FLASH page address;
idata unsigned long flash_page_2; // Second FLASH page address;
idata unsigned int card_status; // Stores status returned from MMC;
idata unsigned int counter; // Byte counter used for writes to
// local copy of data block;
idata unsigned int temp_length;
unsigned int index; // Pointer into local copy of data
// block, used during modification;
if(length > 512) return 0; // Check for valid data length;
// Calculate first FLASH page address;
flash_page_1 = address & ~(PHYSICAL_BLOCK_SIZE-1);
// Calculate second FLASH page address;
flash_page_2 = (address+length-1) & ~(PHYSICAL_BLOCK_SIZE-1);
if(flash_page_1 == flash_page_2) // Handle single FLASH block condition;
{
// Set block length to default block
// size (512 bytes);
card_status = MMC_Command_Exec(SET_BLOCKLEN,
(unsigned long)PHYSICAL_BLOCK_SIZE,
EMPTY);
// Read data block into EEPROM;
card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
counter = 0;
while(length>0) // This loop updates the temporary
{ // MMC Page(in EEPROM) with the contents
if(length<=64) // of the current temperature buffer;
{
counter = length;
length = 0;
}
else
{
counter = 64;
length -= 64;
}
// Read temperature data
EEPROM_ReadArray(&EEPROM_PageBuffer[0],wdata,counter);
// Store in temp MMC page(in EEPROM);
EEPROM_WriteArray(index, &EEPROM_PageBuffer[0], counter);
wdata+=EEPROM_PAGE_SIZE; // Update temperature buffer pointer;
index+=EEPROM_PAGE_SIZE; // Update temp MMC page (in EEPROM)
// pointer;
counter = 0;
}
// Write modified block back to MMC;
card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
}
else // Handle multiple FLASH block
{ // condition;
// Set block length to default block
// size (512 bytes);
card_status = MMC_Command_Exec(SET_BLOCKLEN,
(unsigned long)PHYSICAL_BLOCK_SIZE,
EMPTY);
// Read first data block into EEPROM;
card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
temp_length = length;
length = (unsigned int)(flash_page_2 - address);
while(length>0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -