📄 mmc_datalogger_eeprom.c
字号:
}
}
//-----------------------------------------------------------------------------
// LogInit
//-----------------------------------------------------------------------------
// Initialize the Log Entry space (all zeros);
//
void LogInit (LOG_ENTRY *pEntry)
{
pEntry->wTemp = 0;
pEntry->uDay = 0;
pEntry->bHour = 0;
pEntry->bMin = 0;
pEntry->bSec = 0;
}
//-----------------------------------------------------------------------------
// MMC_Command_Exec
//-----------------------------------------------------------------------------
//
// This function generates the necessary SPI traffic for all MMC SPI commands.
// The three parameters are described below:
//
// cmd: This parameter is used to index into the command table and read
// the desired command. The Command Table Index Constants allow the
// caller to use a meaningful constant name in the cmd parameter
// instead of a simple index number. For example, instead of calling
// MMC_Command_Exec (0, argument, pchar) to send the MMC into idle
// state, the user can call
// MMC_Command_Exec (GO_IDLE_STATE, argument, pchar);
//
// argument: This parameter is used for MMC commands that require an argument.
// MMC arguments are 32-bits long and can be values such as an
// an address, a block length setting, or register settings for the
// MMC.
//
// pchar: This parameter is a pointer to the EEPROM data location for MMC
// data operations. When a read or write occurs, data will be stored
// or retrieved from the location pointed to by pchar.
//
// The MMC_Command_Exec function indexes the command table using the cmd
// parameter. It reads the command table entry into memory and uses information
// from that entry to determine how to proceed. Returns 16-bit card response
// value.
//
unsigned int MMC_Command_Exec (unsigned char cmd, unsigned long argument,
unsigned int pchar)
{
idata command current_command; // Local space for the command table
// entry;
idata ULONG long_arg; // Union variable for easy byte
// transfers of the argument;
// Static variable that holds the
// current data block length;
static unsigned long current_blklen = 512;
// Temp variable to preserve data block
idata unsigned long old_blklen = 512;
// length during temporary changes;
idata unsigned int counter = 0; // Byte counter for multi-byte fields;
idata UINT card_response; // Variable for storing card response;
idata unsigned char data_resp; // Variable for storing data response;
idata unsigned char dummy_CRC; // Dummy variable for storing CRC field;
// Index variable for keeping track of
// where you are in the EEPROM page;
idata unsigned char EEPROM_BufferIndex;
current_command = commandlist[cmd]; // Retrieve desired command table entry
// from code space;
SPI0DAT = 0xFF; // Send buffer SPI clocks to ensure no
while(!SPIF){} // MMC operations are pending;
SPIF = 0;
NSSMD0 = 0; // Select MMC by pulling CS low;
SPI0DAT = 0xFF; // Send another byte of SPI clocks;
while(!SPIF){}
SPIF = 0;
// Issue command opcode;
SPI0DAT = (current_command.command_byte | 0x40);
long_arg.l = argument; // Make argument byte addressable;
// If current command changes block
// length, update block length variable
// to keep track;
if(current_command.command_byte == 16)
{
current_blklen = argument; // Command is a read, set local block
} // length;
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
// 0xFF;
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;
data_resp = SPI0DAT;
// Send data read from MMC to EEPROM
// buffer;
EEPROM_WriteByte(pchar,data_resp);
pchar++;
}
}
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;
EEPROM_BufferIndex = 0;
while(counter < (unsigned int)current_blklen)
{
SPI0DAT = 0x00; // Start SPI transfer;
while(!SPIF){}
SPIF = 0;
// Build a small buffer of data
// in local memory;
EEPROM_PageBuffer[EEPROM_BufferIndex] = SPI0DAT;
EEPROM_BufferIndex++;
// If the buffer reaches the size of a
// physical EEPROM page, write buffered
// data out to EEPROM and reset buffer;
if(EEPROM_BufferIndex >= EEPROM_PAGE_SIZE)
{
// Send data to EEPROM;
EEPROM_WriteArray(pchar, &EEPROM_PageBuffer[0], EEPROM_PAGE_SIZE);
// Increment EEPROM page;
pchar += EEPROM_PAGE_SIZE;
EEPROM_BufferIndex = 0; // Reset local buffer index;
}
counter++; // Increment data byte counter;
}
// Write any remaining buffered data to
if(EEPROM_BufferIndex != 0) // EEPROM;
EEPROM_WriteArray(pchar, &EEPROM_PageBuffer[0], EEPROM_BufferIndex);
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;
counter = 0; // Reset byte counter;
while(!SPIF){}
SPIF = 0;
// Prime Buffer Index
EEPROM_BufferIndex = EEPROM_PAGE_SIZE;
// Write <current_blklen> bytes to MMC;
while(counter < (unsigned int)current_blklen)
{ // When EEPROM page is full, reset local
// buffer and move to next EEPROM page;
if(EEPROM_BufferIndex > EEPROM_PAGE_SIZE-1)
{
// Send data to EEPROM;
EEPROM_ReadArray(&EEPROM_PageBuffer[0],pchar,EEPROM_PAGE_SIZE);
// Reset local buffer index;
EEPROM_BufferIndex = 0;
// Update EEPROM page;
pchar += EEPROM_PAGE_SIZE;
}
// Write data byte out through SPI;
SPI0DAT = EEPROM_PageBuffer[EEPROM_BufferIndex];
EEPROM_BufferIndex++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -