?? dataflash.c
字號(hào):
//@+leo-ver=4
//@+node:@file dataflash.c
//@<<DISCLAIMER>>
//@+node:<<DISCLAIMER>>
// ----------------------------------------------------------------------------
// ATMEL Microcontroller Software Support - ROUSSET -
// ----------------------------------------------------------------------------
// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------
//@-node:<<DISCLAIMER>>
//@nl
#include "main.h"
#include "dataflash.h"
#define AT91C_DF_PAGE_SIZE 1056/4
//*----------------------------------------------------------------------------
//* \fn AT91F_SpiInit
//* \brief
//*----------------------------------------------------------------------------
void AT91F_SpiInit(unsigned int uPCS)
{
volatile unsigned int uDummy;
// Open PIO for SPI0
// AT91F_SPI0_CfgPIO();
// AT91F_PIO_CfgPullup(AT91C_BASE_PIOA, 0xFFFFFFFF);
// Configure PIO
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOA, // PIO controller base address
((unsigned int) AT91C_PA1_SPI0_MOSI) |
((unsigned int) AT91C_PA0_SPI0_MISO) |
((unsigned int) AT91C_PA2_SPI0_SPCK), // Peripheral A
0); // Peripheral B
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOC, // PIO controller base address
0, // Peripheral A
((unsigned int) AT91C_PC11_SPI0_NPCS1)); // Peripheral B
// Enables the SPI0 Clock
AT91F_SPI0_CfgPMC();
// Reset SPI0
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;
// Configure SPI0 in Master Mode with No CS selected
AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
// Configure CSx
if (uPCS == AT91C_SPI_PCS0_DATAFLASH)
*(AT91C_SPI0_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | ((AT91C_MASTER_CLOCK / AT91C_SPI_CLK) << 8);
else // if (uPCS == AT91C_SPI_PCS1_DATAFLASH)
*(AT91C_SPI0_CSR + 1) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | ((AT91C_MASTER_CLOCK / AT91C_SPI_CLK) << 8);
// Choose CSx
AT91C_BASE_SPI0->SPI_MR &= 0xFFF0FFFF;
AT91C_BASE_SPI0->SPI_MR |= ((uPCS << 16) & AT91C_SPI_PCS);
// SPI_Enable
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
for (uDummy=0; uDummy<100000; uDummy++);
uDummy = AT91C_BASE_SPI0->SPI_SR;
uDummy = AT91C_BASE_SPI0->SPI_RDR;
}
//*-----------------------------------------------------------------------------
//* \fn : AT91F_DF_wait_ready
//* \brief
//*-----------------------------------------------------------------------------
char AT91F_DF_wait_ready(AT91PS_DF pDataFlash)
{
unsigned int timeout = 0;
while (timeout++ < AT91C_DF_TIMEOUT)
{
if (AT91F_DF_get_status(pDataFlash))
{
if (AT91F_DF_is_ready(pDataFlash))
return 1;
}
}
return 0;
}
//@<<AT91F_DF_send_command>>
//@+node:<<AT91F_DF_send_command>>
//*----------------------------------------------------------------------------
//* \fn AT91F_DataFlashSendCommand
//* \brief Generic function to send a command to the dataflash
//*----------------------------------------------------------------------------
char AT91F_DF_send_command (
AT91PS_DF pDataFlash,
unsigned char bCmd, // Command value
unsigned char bCmdSize, // Command Size
char *pData, // Data to be sent
unsigned int dDataSize, // Data Size
unsigned int dAddress) // Dataflash Address
{
unsigned int dInternalAdr;
AT91PS_PDC pPdc;
// Try to get the dataflash semaphore
if ( (pDataFlash->bSemaphore) != UNLOCKED)
return (char) 0;
pDataFlash->bSemaphore = LOCKED;
// Compute command pattern
dInternalAdr = ((dAddress / AT91C_PAGE_SIZE(pDataFlash)) << AT91C_PAGE_OFFSET(pDataFlash)) \
+ (dAddress % AT91C_PAGE_SIZE(pDataFlash));
if (AT91C_DF_NB_PAGE(pDataFlash) >= 16384)
{
pDataFlash->command[0] = (bCmd & 0x000000FF) | \
((dInternalAdr & 0x0F000000) >> 16) | \
((dInternalAdr & 0x00FF0000) >> 0) | \
((dInternalAdr & 0x0000FF00) << 16);
pDataFlash->command[1] = (dInternalAdr & 0x000000FF);
if ((bCmd != DB_CONTINUOUS_ARRAY_READ) && (bCmd != DB_PAGE_READ))
bCmdSize++;
}
else
{
pDataFlash->command[0] = (bCmd & 0x000000FF) | \
((dInternalAdr & 0x00FF0000) >> 8) | \
((dInternalAdr & 0x0000FF00) << 8) | \
((dInternalAdr & 0x000000FF) << 24);
pDataFlash->command[1] = 0;
}
// Send Command and data through the SPI
pPdc = (AT91PS_PDC) &(pDataFlash->pSpi->SPI_RPR);
AT91F_PDC_DisableRx(pPdc);
AT91F_PDC_SetRx(pPdc, (char *) &(pDataFlash->command), bCmdSize);
AT91F_PDC_SetNextRx(pPdc, pData, dDataSize);
AT91F_PDC_DisableTx(pPdc);
AT91F_PDC_SetTx(pPdc, (char *) &(pDataFlash->command), bCmdSize);
AT91F_PDC_SetNextTx(pPdc, pData, dDataSize);
AT91F_PDC_EnableRx(pPdc);
AT91F_PDC_EnableTx(pPdc);
while (AT91F_DF_is_busy(pDataFlash) == LOCKED);
return 1;
}
//@nonl
//@-node:<<AT91F_DF_send_command>>
//@nl
//@<<AT91F_DF_is_busy>>
//@+node:<<AT91F_DF_is_busy>>
//*----------------------------------------------------------------------------
//* \fn AT91F_DataFlashHandler
//* \brief SPI Fixed Peripheral C interrupt handler.
//*----------------------------------------------------------------------------
AT91S_DF_SEM AT91F_DF_is_busy(
AT91PS_DF pDataFlash)
{
AT91PS_PDC pPdc;
AT91PS_SPI pSpi = pDataFlash->pSpi;
unsigned int dStatus = pSpi->SPI_SR;
//* If End of Receive Transfer interrupt occurred
if (( dStatus & AT91C_SPI_RXBUFF))
{
pPdc = (AT91PS_PDC) &(pDataFlash->pSpi->SPI_RPR);
AT91F_PDC_DisableTx(pPdc);
AT91F_PDC_DisableRx(pPdc);
// Release the semaphore
pDataFlash->bSemaphore = UNLOCKED;
return UNLOCKED;
}
return pDataFlash->bSemaphore;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_DataFlash_Write_Page
//* \brief Copy Flash content in First DataFlash page
//*----------------------------------------------------------------------------
void AT91F_DataFlash_Write_Page(AT91PS_DF pDf)
{
unsigned int dAddress = 0;
// Write a page
AT91F_DF_write_buf1(pDf, AT91C_IROM, AT91C_PAGE_SIZE(pDf), dAddress);
AT91F_DF_wait_ready(pDf);
AT91F_DF_page_erase(pDf, dAddress);
AT91F_DF_wait_ready(pDf);
AT91F_DF_pgm_buf1(pDf, AT91C_IROM, AT91C_PAGE_SIZE(pDf), dAddress);
AT91F_DF_wait_ready(pDf);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_DataFlash_Read_Page
//* \brief Read First DataFlash page
//*----------------------------------------------------------------------------
void AT91F_DataFlash_Read_Page(AT91PS_DF pDf, char *pData)
{
unsigned int dAddress = 0;
AT91F_DF_continuous_read(pDf, pData, AT91C_PAGE_SIZE(pDf), dAddress);
AT91F_DF_wait_ready(pDf);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_DataflashProbe
//* \brief
//*----------------------------------------------------------------------------
int AT91F_DataflashProbe(AT91PS_DF pDf)
{
char *pResult = (char *)(pDf->command);
AT91F_DF_get_status(pDf);
return (pResult[1] & 0x3C);
}
//*------------------------------------------------------------------------------
//* Function Name : AT91F_DataflashInit
//* \brief
//*------------------------------------------------------------------------------
int AT91F_DataflashInit (AT91PS_DF pDf)
{
int dfcode = 0;
int status = 1;
// Default: AT45DB321B
pDf->dfDescription.pages_number = 8192;
pDf->dfDescription.pages_size = 528;
pDf->dfDescription.page_offset = 10;
dfcode = AT91F_DataflashProbe (pDf);
switch (dfcode)
{
case AT45DB011B:
pDf->dfDescription.pages_number = 512;
pDf->dfDescription.pages_size = 264;
pDf->dfDescription.page_offset = 9;
break;
case AT45DB021B:
pDf->dfDescription.pages_number = 1024;
pDf->dfDescription.pages_size = 264;
pDf->dfDescription.page_offset = 9;
break;
case AT45DB041B:
pDf->dfDescription.pages_number = 2048;
pDf->dfDescription.pages_size = 264;
pDf->dfDescription.page_offset = 9;
break;
case AT45DB081B:
pDf->dfDescription.pages_number = 4096;
pDf->dfDescription.pages_size = 264;
pDf->dfDescription.page_offset = 9;
break;
case AT45DB161B:
pDf->dfDescription.pages_number = 4096;
pDf->dfDescription.pages_size = 528;
pDf->dfDescription.page_offset = 10;
break;
case AT45DB321B:
pDf->dfDescription.pages_number = 8192;
pDf->dfDescription.pages_size = 528;
pDf->dfDescription.page_offset = 10;
break;
case AT45DB642:
pDf->dfDescription.pages_number = 8192;
pDf->dfDescription.pages_size = 1056;
pDf->dfDescription.page_offset = 11;
break;
case AT45DB1282:
pDf->dfDescription.pages_number = 16384;
pDf->dfDescription.pages_size = 1056;
pDf->dfDescription.page_offset = 11;
break;
case AT45DB2562:
pDf->dfDescription.pages_number = 16384;
pDf->dfDescription.pages_size = 2112;
pDf->dfDescription.page_offset = 12;
break;
case AT45DB5122:
pDf->dfDescription.pages_number = 32768;
pDf->dfDescription.pages_size = 2112;
pDf->dfDescription.page_offset = 12;
break;
default:
status = 0;
break;
}
return status;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_Test_SPI_DataFlash
//* \brief
//*----------------------------------------------------------------------------
int AT91F_Test_SPI_DataFlash(unsigned int uPCS)
{
AT91S_DF sDF;
AT91PS_DF pDf = (AT91PS_DF)&sDF;
unsigned int pData[AT91C_DF_PAGE_SIZE];
unsigned int *pSource = (unsigned int *)AT91C_IROM;
int i = 0;
pDf->pSpi = AT91C_BASE_SPI0;
pDf->bSemaphore = UNLOCKED;
AT91F_SpiInit(uPCS);
if (!AT91F_DataflashInit(pDf))
return -1;
AT91F_DataFlash_Write_Page(pDf);
AT91F_DataFlash_Read_Page(pDf, (char *)pData);
// Compare Page
while ((i<(pDf->dfDescription.pages_size/4)) && (pData[i] == pSource[i]))
i++;
return (i<(pDf->dfDescription.pages_size/4)) ? -2 : 0;
}
//@-node:<<AT91F_DF_is_busy>>
//@nl
//@-node:@file dataflash.c
//@-leo
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -