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

📄 main.c

📁 OM_Services_test例程可以在片上SRAM、片外SDRAM、片外Flash中运行。 注意:在片外Flash中运行时
💻 C
字号:
//*----------------------------------------------------------------------------
//*         ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : main.c
//* Object              : main application written in C
//* Creation            : FB   21st March 2003
//*
//*----------------------------------------------------------------------------
#include <stdio.h>
#include <AT91RM9200.H>                 // AT91RM9200 definitions
#include <lib_AT91RM9200.h>             // Library function definitions

#define AT91RM9200
#include "embedded_services.h"

#define AT91C_SPI_PCS0_SERIAL_DATAFLASH		0xE     	// Chip Select 0 : NPCS0 %1110
#define AT91C_DATAFLASH_TIMEOUT				10000   	// Timeout for AT91F_DataFlashWaitReady
#define BUFFER_SIZE_DATAFLASH				1056		// Size of the dataflash
#define MASTER_CLOCK						60000000	// MCK
#define MEMORY_SIZE_MAX						(2*1024)	// Memory size for the application area uploaded in SRAM
#define PAGE_NUMBER							50			// DataFlash Page Number for test

////////////////////////////////////////////////////////////////////////////////
// External Functions
////////////////////////////////////////////////////////////////////////////////
extern void AT91F_DBGU_Printk(char *);
extern void AT91F_ASM_SPI_Handler(void);
extern void AT91F_ASM_ST_DBGU_Handler(void);
extern void AT91F_LowLevelInit(void);
////////////////////////////////////////////////////////////////////////////////
// Allocation of the service structures
////////////////////////////////////////////////////////////////////////////////

// "ROM Entry" Service
AT91S_RomBoot const *pAT91;

// "SBuffer and Pipe" structures for "Xmodem" Service
AT91S_SBuffer   	sXmBuffer;
AT91S_Pipe      	xmodemPipe;
AT91S_SvcXmodem 	svcXmodem;

// "Tempo" Service
AT91S_CtlTempo  	ctlTempo;

// "DataFlash" Service
AT91S_SvcDataFlash 	svcDataFlash;
AT91S_Dataflash		DeviceAT45DB;

////////////////////////////////////////////////////////////////////////////////
// Global Variables
////////////////////////////////////////////////////////////////////////////////
char					Buffer_Dataflash[BUFFER_SIZE_DATAFLASH];
char					Buffer_Xmodem[MEMORY_SIZE_MAX];
volatile unsigned int 	StTick;					// system timer tick count for timeout 
char					EndOfTransmission=0; 	// flag for end of xmodem
char   					message[60];
unsigned int   			Reference_CRC;
unsigned int   			CRC;

//*----------------------------------------------------------------------------
//* \fn    AT91F_DataFlashWaitReady
//* \brief wait for dataflash ready (bit7 of the status register == 1)
//*----------------------------------------------------------------------------
AT91S_SvcDataFlashStatus AT91F_DataFlashWaitReady(unsigned int timeout)
{
	unsigned int 	i;

	svcDataFlash.DataFlashDesc.DataFlash_state = IDLE;	

	do
	{
		svcDataFlash.Status(&(svcDataFlash.DataFlashDesc));
		timeout--;
		// dummy waiting time
		for(i=0;i<10;i++);
	}
	while( ((svcDataFlash.DataFlashDesc.DataFlash_state & 0x80) != 0x80) && (timeout>0) );

	if((svcDataFlash.DataFlashDesc.DataFlash_state & 0x80) != 0x80)
		return DATAFLASH_ERROR;
		
	return DATAFLASH_OK;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_SPI_CfgSPI
//* \brief Config SPI IP
//*----------------------------------------------------------------------------
void  AT91F_SPI_CfgSPI(void)
{
	// Reset the SPI
	AT91F_SPI_Reset(AT91C_BASE_SPI);

    // Configure SPI in Master Mode with No CS selected !!!  
	AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS);

	// Configure SPI CS0 for Serial svcDataFlash AT45DBxx
	AT91F_SPI_CfgCs(0, AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((MASTER_CLOCK / (2*DATAFLASH_CLK)) << 8));

    // Enable the SPI
    AT91F_SPI_Enable(AT91C_BASE_SPI);
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_CfgDataFlash
//* \brief Config svcDataFlash Structures
//*----------------------------------------------------------------------------
void AT91F_CfgDataFlash (void)
{
	// Init AT91S_Dataflash Structure for AT45DB642
	DeviceAT45DB.pages_number = 8192;
	DeviceAT45DB.pages_size   = 1056;
	DeviceAT45DB.page_offset  = 11;
	DeviceAT45DB.byte_mask    = 0x700;	

	// Init AT91S_DataflashDesc Structure
	svcDataFlash.DataFlashDesc.state 			= IDLE;
	svcDataFlash.DataFlashDesc.DataFlash_state	= IDLE;

	// Init AT91S_SvcDataFlash Global Structure
	svcDataFlash.pDevice 		= &DeviceAT45DB;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_CfgSPIForDataFlash
//* \brief This function initialize SPI for a serial dataflash
//* \brief Serial svcDataFlash AT45DB on CS0
//*----------------------------------------------------------------------------
void AT91F_CfgSPIForDataFlash()
{
	AT91F_DBGU_Printk("\n\rInit SPI Interface\n\r");

	// Init SPI for svcDataFlash interface
	AT91F_SPI_CfgPIO();	
	AT91F_SPI_CfgPMC();
	AT91F_SPI_CfgSPI();
	AT91F_PDC_Open(AT91C_BASE_PDC_SPI);
	
    AT91F_CfgDataFlash();
	
	// Configure SPI interrupt 
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
						 AT91C_ID_SPI,
						 3,
						 AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
						 AT91F_ASM_SPI_Handler);
						 
	// Enable SPI interrupt
	AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_SPI);
}

//*----------------------------------------------------------------------------
//* \fn    AT91_XmodemComplete
//* \brief Allows to correctly complete xmodem end of transmission
//*----------------------------------------------------------------------------
void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid)
{
	// stop the Xmodem tempo 
	svcXmodem.tempo.Stop(&(svcXmodem.tempo));
	
	// upload complete
	EndOfTransmission = 1;
}

//*----------------------------------------------------------------------------
//* \fn    AT91_XmodemProtocol
//* \brief Allows to correctly complete xmodem end of transmission
//*----------------------------------------------------------------------------
void AT91_XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
{
	AT91PS_USART  pUsart     = svcXmodem.pUsart;
			
	svcXmodem.tempo.Start(&(svcXmodem.tempo), 10, 0, AT91_XmodemComplete, pUsart);								
}

///////////////////////////////////////////////////////////////////////////////////////////
//	Interrupt handlers
///////////////////////////////////////////////////////////////////////////////////////////

//*----------------------------------------------------------------------------
//* \fn    AT91F_SPI_Handler
//* \brief SPI Handler
//*----------------------------------------------------------------------------
void AT91F_SPI_Handler(void)
{
	int status;

	status = ( AT91C_BASE_SPI->SPI_SR & AT91C_BASE_SPI->SPI_IMR );

	svcDataFlash.Handler(&svcDataFlash, status);
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_ST_DBGU_Handler
//* \brief C Interrupt handler for Interrupt source 1
//*----------------------------------------------------------------------------
void AT91F_ST_DBGU_Handler(void)
{
	volatile unsigned int csr = AT91C_BASE_DBGU->DBGU_CSR;

	// ========== Systimer interrupt ============== //
	if (AT91C_BASE_ST->ST_SR & AT91C_ST_PITS) {
		StTick++;
		ctlTempo.CtlTempoTick(&ctlTempo);
		return;
	}

	// ========== DBGU interrupt ============== //
	if (csr & (AT91C_US_PARE  | AT91C_US_FRAME | AT91C_US_OVRE | AT91C_US_RXBRK)) 
	{
		// Stop previous Xmodem transmission
		AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTSTA;
		AT91C_BASE_DBGU->DBGU_IDR = AT91C_US_ENDRX;
		AT91C_BASE_DBGU->DBGU_IER = AT91C_US_RXRDY | AT91C_US_COMM_RX;	
			
	} else if (csr & ((AT91C_US_TXRDY | AT91C_US_ENDTX | AT91C_US_TXEMPTY) | 
				   (AT91C_US_RXRDY | AT91C_US_ENDRX | AT91C_US_TIMEOUT) | 
				   AT91C_US_RXBUFF))
			{
				svcXmodem.Handler(&svcXmodem, csr);
			}
}

//*----------------------------------------------------------------------------
//* \fn    main
//* \brief main function
//*----------------------------------------------------------------------------
int main()
{
	int i;
	int status;
	
	AT91PS_Buffer  	pXmBuffer;
	AT91PS_SvcComm 	pSvcXmodem;

	AT91F_LowLevelInit();
	AT91F_DBGU_Printk("\n\n\r===========================================");
	AT91F_DBGU_Printk("\n\rAT91RM9200 Basic ROM Services Test\n\r");
	AT91F_DBGU_Printk("===========================================\n\r");

	// Call Open methods:
	pAT91 = AT91C_ROM_BOOT_ADDRESS;

///////////////////////////////////////////////////////////////////////////////////////////
//  Init of the service Tempo
///////////////////////////////////////////////////////////////////////////////////////////

	// Open Tempo service
	pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC) );
	ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC) );

///////////////////////////////////////////////////////////////////////////////////////////
//  Init of the service Xmodem
///////////////////////////////////////////////////////////////////////////////////////////

	// Open SBuffer structure 
	pXmBuffer	= pAT91->OpenSBuffer(&sXmBuffer);

	// Open Xmodem service
	pSvcXmodem	= pAT91->OpenSvcXmodem(&svcXmodem,(AT91PS_USART) AT91C_BASE_DBGU, &ctlTempo);
	
	// Open Pipe structure
	pAT91->OpenPipe(&xmodemPipe, pSvcXmodem, pXmBuffer);

///////////////////////////////////////////////////////////////////////////////////////////
//  Init of the service svcDataFlash
///////////////////////////////////////////////////////////////////////////////////////////

	// Init of the SPI
	AT91F_CfgSPIForDataFlash();
	AT91F_SPI_CfgPCS(AT91C_BASE_SPI,AT91C_SPI_PCS0_SERIAL_DATAFLASH);

	// Open the service
	pAT91->OpenSvcDataFlash (AT91C_BASE_PMC, &svcDataFlash);

	// Wait DataFlash Ready
	AT91F_DataFlashWaitReady(AT91C_DATAFLASH_TIMEOUT);

///////////////////////////////////////////////////////////////////////////////////////////
//  Init the Uploader
///////////////////////////////////////////////////////////////////////////////////////////

	// Initialize the Interrupt Source 1 for SysTimer and DBGU
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
						 AT91C_ID_SYS,
						 AT91C_AIC_PRIOR_HIGHEST,
						 AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,
						 AT91F_ASM_ST_DBGU_Handler);
						 
	// Enable SysTimer and DBGU interrupt
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);

///////////////////////////////////////////////////////////////////////////////////////////
//  Enter the uploading by Xmodem -> Service Xmodem + Service Tempo used
///////////////////////////////////////////////////////////////////////////////////////////

	AT91F_DBGU_Printk("\n\rPlease Send the BinaryToUpload.bin by Xmodem:\n\r");
	
	xmodemPipe.Read(&xmodemPipe, (char *) Buffer_Xmodem, MEMORY_SIZE_MAX, AT91_XmodemProtocol, (void *) Buffer_Xmodem);
	while (EndOfTransmission != 1);

	AT91F_DBGU_Printk("\n\rXmodem Transmission Completed !!!\n\r");
	
///////////////////////////////////////////////////////////////////////////////////////////
//  Enter DataFlash Test -> Service DataFlash + Service CRC used
///////////////////////////////////////////////////////////////////////////////////////////

	AT91F_DBGU_Printk("\n\rEnter DataFlash <-> CRC Test\n\r");

	// Copy on Buffer_Dataflash a part of the uploaded binary, the size of a dataflash page
	for(i=0;i<(DeviceAT45DB.pages_size);i++)
		Buffer_Dataflash[i] = Buffer_Xmodem[i];

	// Compute CRC of the binary downloaded by Xmodem
	Reference_CRC = 0xFFFFFFFF;
	pAT91->CRC32( (unsigned char *) Buffer_Dataflash,DeviceAT45DB.pages_size,&Reference_CRC);

    sprintf(message,"\n\rCRC32 after Xmodem Upload= 0x%x",Reference_CRC);
    AT91F_DBGU_Printk(message);

	// Write On PAGE_NUMBER  
	status = svcDataFlash.PagePgmBuf(&svcDataFlash,
							DB_PAGE_PGM_BUF1,
							(unsigned char *) Buffer_Dataflash,
							PAGE_NUMBER*DeviceAT45DB.pages_size,
							DeviceAT45DB.pages_size);			 

	// Wait DataFlash Ready
	AT91F_DataFlashWaitReady(AT91C_DATAFLASH_TIMEOUT);

	if(status == 0x1)
		AT91F_DBGU_Printk("\n\rWrite Successful");	
    else
    	{ 
		AT91F_DBGU_Printk("\n\rWrite Failed");
		return 0;	
		}
		
	// Check if erase was correctly done
 	for(i = 0;i < DeviceAT45DB.pages_size;i++)
		Buffer_Dataflash[i] = 0x00;

	status = svcDataFlash.PageRead(&svcDataFlash,
						 (PAGE_NUMBER*DeviceAT45DB.pages_size),
						 (unsigned char *) Buffer_Dataflash,
						 DeviceAT45DB.pages_size);

	// Wait DataFlash Ready
	AT91F_DataFlashWaitReady(AT91C_DATAFLASH_TIMEOUT);

	if(status == 0x1)
		AT91F_DBGU_Printk("\n\rRead Successful");	
    else
    	{ 
		AT91F_DBGU_Printk("\n\rRead Failed");
		return 0;	
		}
		
	// Compute the Buffer_Dataflash CRC value
	CRC = 0xFFFFFFFF;
	pAT91->CRC32( (unsigned char *) Buffer_Dataflash,DeviceAT45DB.pages_size,&CRC);

    sprintf(message,"\n\rCRC32 after Write then Read on Dataflash = 0x%x",CRC);
    AT91F_DBGU_Printk(message);	

	if (CRC == Reference_CRC)
		AT91F_DBGU_Printk("\n\rCRC Comparison Successful");	
	else
		AT91F_DBGU_Printk("\n\rCRC Comparison Failed");
		
	return 0;	
}

⌨️ 快捷键说明

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