📄 mmc_datalogger.c
字号:
// block length command is taking place
// and block length variable must be
// set;
if(current_command.command_byte == 16)
{
current_blklen = argument;
}
// Command byte = 9 or 10 means that a
// 16-byte register value is being read
// from the card, block length must be
// set to 16 bytes, and restored at the
// end of the transfer;
if((current_command.command_byte == 9)||
(current_command.command_byte == 10))
{
old_blklen = current_blklen; // Command is a GET_CSD or GET_CID,
current_blklen = 16; // set block length to 16-bytes;
}
while(!SPIF){} // Wait for initial SPI transfer to end;
SPIF = 0; // Clear SPI Interrupt flag;
// If an argument is required, transmit
// one, otherwise transmit 4 bytes of
// 0x00;
if(current_command.arg_required == YES)
{
counter = 0;
while(counter <= 3)
{
SPI0DAT = long_arg.b[counter];
counter++;
while(!SPIF){}
SPIF = 0;
}
}
else
{
counter = 0;
while(counter <= 3)
{
SPI0DAT = 0x00;
counter++;
while(!SPIF){}
SPIF = 0;
}
}
SPI0DAT = current_command.CRC; // Transmit CRC byte; In all cases
while(!SPIF){} // except CMD0, this will be a dummy
SPIF = 0; // character;
// The command table entry will indicate
// what type of response to expect for
// a given command; The following
// conditional handles the MMC response;
if(current_command.response == R1) // Read the R1 response from the card;
{
do
{
SPI0DAT = 0xFF; // Write dummy value to SPI so that
while(!SPIF){} // the response byte will be shifted in;
SPIF = 0;
card_response.b[0] = SPI0DAT; // Save the response;
}
while((card_response.b[0] & BUSY_BIT));
}
// Read the R1b response;
else if(current_command.response == R1b)
{
do
{
SPI0DAT = 0xFF; // Start SPI transfer;
while(!SPIF){}
SPIF = 0;
card_response.b[0] = SPI0DAT; // Save card response
}
while((card_response.b[0] & BUSY_BIT));
do // Wait for busy signal to end;
{
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
}
while(SPI0DAT == 0x00); // When byte from card is non-zero,
} // card is no longer busy;
// Read R2 response
else if(current_command.response == R2)
{
do
{
SPI0DAT = 0xFF; // Start SPI transfer;
while(!SPIF){}
SPIF = 0;
card_response.b[0] = SPI0DAT; // Read first byte of response;
}
while((card_response.b[0] & BUSY_BIT));
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
card_response.b[1] = SPI0DAT; // Read second byte of response;
}
else // Read R3 response;
{
do
{
SPI0DAT = 0xFF; // Start SPI transfer;
while(!SPIF){}
SPIF = 0;
card_response.b[0] = SPI0DAT; // Read first byte of response;
}
while((card_response.b[0] & BUSY_BIT));
counter = 0;
while(counter <= 3) // Read next three bytes and store them
{ // in local memory; These bytes make up
counter++; // the Operating Conditions Register
SPI0DAT = 0xFF; // (OCR);
while(!SPIF){}
SPIF = 0;
*pchar++ = SPI0DAT;
}
}
switch(current_command.trans_type) // This conditional handles all data
{ // operations; The command entry
// determines what type, if any, data
// operations need to occur;
case RD: // Read data from the MMC;
do // Wait for a start read token from
{ // the MMC;
SPI0DAT = 0xFF; // Start a SPI transfer;
while(!SPIF){}
SPIF = 0;
}
while(SPI0DAT != START_SBR); // Check for a start read token;
counter = 0; // Reset byte counter;
// Read <current_blklen> bytes;
while(counter < (unsigned int)current_blklen)
{
SPI0DAT = 0x00; // Start SPI transfer;
while(!SPIF){}
SPIF = 0;
*pchar++ = SPI0DAT; // Store data byte in local memory;
counter++; // Increment data byte counter;
}
SPI0DAT = 0x00; // After all data is read, read the two
while(!SPIF){} // CRC bytes; These bytes are not used
SPIF = 0; // in this mode, but the placeholders
dummy_CRC = SPI0DAT; // must be read anyway;
SPI0DAT = 0x00;
while(!SPIF){}
SPIF = 0;
dummy_CRC = SPI0DAT;
break;
case WR: // Write data to the MMC;
SPI0DAT = 0xFF; // Start by sending 8 SPI clocks so
while(!SPIF){} // the MMC can prepare for the write;
SPIF = 0;
SPI0DAT = START_SBW; // Send the start write block token;
while(!SPIF){}
SPIF = 0;
counter = 0; // Reset byte counter;
// Write <current_blklen> bytes to MMC;
while(counter < (unsigned int)current_blklen)
{
SPI0DAT = *pchar++; // Write data byte out through SPI;
while(!SPIF){}
SPIF = 0;
counter++; // Increment byte counter;
}
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 char xdata *pchar; // Xdata pointer for storing MMC
// register values;
// Transmit at least 64 SPI clocks
// before any bus comm occurs.
pchar = (unsigned char xdata*)LOCAL_BLOCK;
for(counter = 0; counter < 8; counter++)
{
SPI0DAT = 0xFF;
while(!SPIF){}
SPIF = 0;
}
NSSMD0 = 0; // Select the MMC with the CS pin;
// Send 16 more SPI clocks to
// ensure proper startup;
for(counter = 0; counter < 2; 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -