⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dataflash.c

📁 关于测试at91sam9260的各种驱动和功能的测试源代码。
💻 C
字号:
/*************************************** Copyright (c) *************************************************
*
*			            POLAR STAR
*				   北天星国际有限公司
*				   http://www.po-star.com
*
*文 件 名: dataflash.c    
*
*文件描述:dataflash test
*
*编译环境:ADS1.2
*
********************************************************************************************************/


#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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -