📄 at45db642.c
字号:
Atmal dataflahs AT45DB321B driver for PIC18F452
Posted: Mon Aug 02, 2004 5:02 pm
--------------------------------------------------------------------------------
bonjour,
My DataFlash Drivers
Code:
//---------------------------------------------------------------------------
// Copyright (c) DVSoft 2004
// email dvsoft@club-internet.fr
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation.
//
// This program is distributed in the hope it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANDIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// Originale Unit Name : DTFDriver.c
// Author : Alain
// Date : 15-Avril-2004
// Project : YA1-LOGGER-V3
// Version : 0.9.0.1
// Revision :
//
//----------------------------------------------------------------------------
//
// DataFlash Driver AT45DB321B for CCS compiler
//
// Inactive Clock Polarity High
// level convertor 74F07 Hex inverter/buffer drivers (open-collector)
// Pull-Up resistor 2K2
//
// PIC18F452 TQFP AT45DB321B
//
// RC5 (SDO) -> DTF SI (15)
// RC4 (SDI) <- DTF SO (16)
// RC3 (SCK) -> DTF SCK (14)
// RE2 (/CS) -> DTF /CS (13)
// RE1 (WR) <- DTF RDY/BUSY (1)
// DTF /RESET +3.3V
// DTF /WP +3.3V
//
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Conditional PinDef
//
#ifndef __DTF_PIN_DEF__
#define DTF_READY PIN_E1
#define DTF_CS PIN_E2
#endif
//----------------------------------------------------------------------------
// Conditional code for the dataflash state in eeprom
//
#ifndef __DTF_DATA_STORAGE__
//------------------------------------------------------------------------
// ROM Space free
//
#define PROGRAM_MEMORY_SIZE getenv("PROGRAM_MEMORY")
#define FLASH_ERASE_SIZE getenv("FLASH_ERASE_SIZE")
#define BUFFER_END PROGRAM_MEMORY_SIZE-1
#define BUFFER_START (PROGRAM_MEMORY_SIZE-(FLASH_ERASE_SIZE*2))
//-----------------------------------------------------------------------
// Config ROM Space (Application not for DataFlash)
//
#define CFG_BUFFER_START BUFFER_START
#define CFG_BUFFER_LEN CFG_BUFFER_START+0x000E
//-----------------------------------------------------------------------
// DataFlash ROM Space
//
#define DTF_BUFFER_START (CFG_BUFFER_START+FLASH_ERASE_SIZE)
#define DTF_BUFFER_LEN (DTF_BUFFER_START+0x000E)
//-----------------------------------------------------------------------
// Rom Configuration
//
#org CFG_BUFFER_START, CFG_BUFFER_LEN {}
//-----------------------------------------------------------------------
// DTPageCnt in ROM
//
#org DTF_BUFFER_START, DTF_BUFFER_LEN {}
//---------------------------------------------------------------------------
// DataFlash PageCnt in ROM Space
//
int16 DTFPageCntRomAddress;
#endif
//----------------------------------------------------------------------------
// Dataflash Config
//
const int16 DTFBlockSize = 512; // DTF block Size
const int16 DTFPageSize = 528; // DTF Page Size
const int16 DTFNbrPage = 8192; // DTF Nb Page
//---------------------------------------------------------------------------
// Dataflash Macro
//
// see Dataflash AC Characteristics
// tCSS /CS Setup Time 250 ns
//
#define DTFSelect()\
output_low(DTF_CS);\
delay_cycles(3) // 300 ns PIC18F452 at 40Mhz
#define DTFUnSelect()\
output_high(DTF_CS);\
delay_cycles(3) // 300 ns PIC18F452 at 40Mhz
//---------------------------------------------------------------------------
// DataFlash PIN 1 Ready/Busy
//
//
#define DTFIsReady() (input(DTF_READY))
//---------------------------------------------------------------------------
// DataFlash PageCount
//
int16 DTFPageCnt;
#byte DTFPageCnt_L=DTFPageCnt
#byte DTFPageCnt_H=DTFPageCnt+1
//---------------------------------------------------------------------------
// DataFlash ByteCount
//
int16 DTFByteCnt;
#byte DTFByteCnt_L=DTFByteCnt
#byte DTFByteCnt_H=DTFByteCnt+1
//---------------------------------------------------------------------------
// DataFlash Address
//
int16 DTFAddress;
#byte DTFAddress_L=DTFAddress
#byte DTFAddress_H=DTFAddress+1
//---------------------------------------------------------------------------
// DataFlash Dump PageCnt
//
int16 DTFDumpPageCnt;
//---------------------------------------------------------------------------
// DataFlash Full Flags
//
BOOLEAN DTFFull;
//---------------------------------------------------------------------------
// DataFlash Buffer Select for Double Buffering
//
BOOLEAN DTF_Buffer_2_Active;
//---------------------------------------------------------------------------
// DataFlash Driver State
//
BOOLEAN DTFDriverRun;
//---------------------------------------------------------------------------
// Function : DTFReadStatus(void)
// Input :
// void
// return :
// int The Status register value
// Modify :
// void
//
// Note :
//
//
#separate
int8 DTFReadStatus(void)
{
int8 Status;
//--- Select
DTFSelect();
//--- Command Read Status
spi_write(0x57);
//--- Status Result
Status = spi_read(0);
//--- Unselect
DTFUnSelect();
return (Status);
}
//---------------------------------------------------------------------------
// Function : DTFPageToRam(int16 PageNum)
// Input :
// int16 PageNum Page index to load in memory buffer
// return :
// void
// Modify :
// Load the memory page 'PageNum' in current buffer (1 or 2)
//
// Note :
// Change the active buffer1 or Buffer2
//
#separate
void DTFPageToRam(int16 PageNum)
{
//--- Active buffer to main memory page
DTFAddress = (PageNum << 2);
while (!DTFIsReady());
//--- Select
DTFSelect();
//--- Buffer 2 is Active Buffer
if (DTF_Buffer_2_Active) {
//--- Memory Page To Buffer 1
spi_write(0x53);
//--- Set Buffer 1 Active
DTF_Buffer_2_Active = FALSE;
}// End IF
//--- Buffer 1 is Active Buffer
else {
//--- Memory Page To Buffer 2
spi_write(0x55);
//--- Set Buffer 2 Active
DTF_Buffer_2_Active = TRUE;
}// End Else
//--- 7 high address bits
spi_write(DTFAddress_H);
//--- 6 low address bits
spi_write(DTFAddress_L);
//--- don't care 8 bits
spi_write(0x00);
//--- Unselect
DTFUnSelect();
}
//---------------------------------------------------------------------------
// Function : DTFRAMToPage(int16 PageNum)
// Input :
// int16 PageNum Page index to store
// return :
// void
// Modify :
// Store the current memory buffer in memory page 'PageNum'
// Change the active buffer1 or Buffer2
//
// Note :
//
#separate
void DTFRAMToPage(int16 PageNum)
{
//--- Active buffer to main memory page
DTFAddress = (PageNum << 2);
//--- Wait DTF_Ready
while (!DTFIsReady());
//--- Select
DTFSelect();
//--- Use Buffer 2 ?
if (DTF_Buffer_2_Active) {
//--- Buffer 2 To PAGE With Built In erase
spi_write(0x86);
//--- Set Buffer 1 Active
DTF_Buffer_2_Active = FALSE;
}// End IF
else {
//--- Buffer 1 To PAGE With Built In erase
spi_write(0x83);
//--- Set Buffer 2 Active
DTF_Buffer_2_Active = TRUE;
}// End ELse
//--- 7 high address bits
spi_write(DTFAddress_H);
//--- 6 low address bits
spi_write(DTFAddress_L);
//--- don't care 8 bits
spi_write(0x00);
//--- Unselect
DTFUnSelect();
}
//---------------------------------------------------------------------------
// Function : DTFInitDump(void)
// Input :
// void
// return :
// void
// Modify :
// Set the dataflash page dump 'DTFDumpPageCnt' to 0
// Load the first memory page in memory buffer
//
// Note :
//
#separate
void DTFInitDump(void)
{
//--- First page to dump
DTFDumpPageCnt = 0;
//--- Load first page in memory buffer
DTFPageToRam(DTFDumpPageCnt);
}
#separate
//---------------------------------------------------------------------------
// Function : DTFDumpPacket(void)
// Input :
// void
// return :
// int 0 End off memory pages
// 1 Some memory pages left
//
// Modify :
// increment the dataflash page dump 'DTFDumpPageCnt'
//
// Note :
// Load in memory buffer the next memory page
//
int DTFDumpNextPage(void)
{
//--- Next Page
DTFDumpPageCnt++;
//--- Not in Last Page ?
if (DTFDumpPageCnt < DTFPageCnt) {
//--- Load in memory buffer
DTFPageToRam(DTFDumpPageCnt);
//--- OK
return 1;
}// End If
//--- Fin
return 0;
}
//---------------------------------------------------------------------------
// Function : DTFDumpPacket(void)
// Input :
// void
// return :
// void
//
// Modify :
// void
//
// Note :
// Dump the complet buffer to the serial UART
// Send only the data in Dataflash buffer
//
#separate
void DTFDumpPacket(void)
{
int8 TxBuffer;
int16 ByteCnt;
//--- Wait DTF_Ready
while (!DTFIsReady());
//--- Initialisation
DTFSelect();
//--- Buffer 2 is Active ?
if (DTF_Buffer_2_Active)
spi_write(0x56);
//--- Buffer 1 is Active
else
spi_write(0x54);
//--- 8 Dont'care Byte
spi_write(0x00);
//--- High Byte address
spi_write(0x00);
//--- Low Byte address
spi_write(0x00);
//--- 8 Dont'care Byte
spi_write(0x00);
//--- Byte Count
ByteCnt = DTFPageSize;
//--- Load In Buffer
do {
//--- Read One Byte
TxBuffer = spi_read(0);
//--- Put in serial UART
putc(TxBuffer);
} while (--ByteCnt);
//--- Unselect
DTFUnSelect();
}
//---------------------------------------------------------------------------
// Function : DTFOpen(void)
// Input :
// void
// return :
// void
//
// Modify :
// Set the flag 'DTFDriverRun' to TRUE if ok
// FALSE if not Ok
// Set the Flag 'DTFFull' to TRUE if (DTFPageCnt == DTFNbrPage)
//
// Set the Byte Count 'DTFByteCnt' to 0
//
// Set the Dump page counter 'DTFDumpPageCnt' to 0
//
// Note :
//
#separate
void DTFOpen(void)
{
int8 Status;
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_4|SPI_SAMPLE_AT_END); //--- Setup du SPI
DTF_Buffer_2_Active = FALSE; //--- Buffer 1 Is Active Buffer
#ifndef __DTF_DATA_STORAGE__
DTFPageCntRomAddress = DTF_BUFFER_START; //--- DataFlash Storage Adresse
DTFPageCnt = read_program_eeprom(DTFPageCntRomAddress); //--- DataFlashPageCnt
#endif
DTFReadStatus(); //--- Read the status register
Status = DTFReadStatus(); //--- Read 2 just in case
//--- Status OK ?
//
// AT45DB321B (TABLE 4 and 5 page 8) Using Atmel's DataFlash document
//
// bit 7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
// Rdy/Busy Compare Density code reserved
// 1 0 1 1 0 1 0 0
//
if (Status & 0x80) {
//--- i store the lastpage value in eeprom area
// so you must provide this data
//
DTFFull = (DTFPageCnt == DTFNbrPage);
DTFByteCnt = 0; //--- First Word
DTFDumpPageCnt = 0; //--- Dump page Count
DTFDriverRun = TRUE; //--- DataFlash OK
}// End If
else
//--- DataFlash HS ?
DTFDriverRun = FALSE;
}
//---------------------------------------------------------------------------
// Function : DTFWriteToFlash(int8 Data)
// Input :
// int8 Data Data to flash
// return :
// void
//
// Modify :
// Set the flag DTFFul if last page
//
// Note :
// Automatique store to memory area with built-in-erase when the ram buffer
// is full. Use double bufferring for fast operation
//
#separate
void DTFWriteToFlash(int8 Data)
{
if (!DTFDriverRun) //--- Drivers RUN ?
return;
if (DTFFull) //--- DTF Full
return;
while (!DTFIsReady()); //--- Wait Ready
DTFSelect(); //--- Start Write Ram
if (DTF_Buffer_2_Active) //--- Write To Buffer 1 ?
spi_write(0x87);
else //--- Write to Buffer 2
spi_write(0x84);
spi_write(0x00); //--- 8 Don't care Bit
spi_write(DTFByteCnt_H); //--- High Byte address
spi_write(DTFByteCnt_L); //--- Low Byte address
spi_write(Data); //--- Write The Value
DTFUnSelect(); //--- UnSelect
DTFByteCnt++; //--- Next Word Address In DataFlash
if (DTFByteCnt >= DTFPageSize) { //--- Last page Byte ?
DTFByteCnt = 0; //--- WriteRam Start Addresse
DTFRAMToPage(DTFPageCnt);//--- RAM To Memory page with builtin erase
DTFPageCnt++; //--- Next Page
erase_program_eeprom(DTFPageCntRomAddress); //--- Store the Last Page Value in PIC eeprom
write_program_eeprom(DTFPageCntRomAddress,DTFPageCnt);
if (DTFPageCnt >= DTFNbrPage) //--- Last Page ?
DTFFull = TRUE;
}// End IF
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -