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

📄 main.c

📁 This zip file shows the use ROM Services in order to speed up an application and reduce its code siz
💻 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   21/11/2002
//*
//*----------------------------------------------------------------------------
#include <stdio.h>

#include "embedded_services.h"
#include "lib_AT91RM9200.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						(1*1024*1024)	// Max Size of the downloaded file 1Mo
#define PAGE_NUMBER							0				// DataFlash Page Number for test
#define AT91C_BASE_LOAD_ADDRESS_FLASH		0x0000	  		// Page 0

////////////////////////////////////////////////////////////////////////////////
// External Functions
////////////////////////////////////////////////////////////////////////////////
extern void 				AT91F_DBGU_Printk(char *);
extern void 				AT91F_ASM_SPI_Handler(void);
extern void 				AT91F_ASM_ST_DBGU_Handler(void);
extern AT91S_SvcCommStatus 	AT91F_SvcXmodemReadHandler_Overloaded(AT91PS_SvcXmodem,unsigned int);

////////////////////////////////////////////////////////////////////////////////
// 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_Xmodem[132];
volatile unsigned int 	StTick;					// system timer tick count for timeout 
char					EndOfTransmission=0; 	// flag for end of xmodem
char   					message[60];
volatile int			destination = AT91C_BASE_LOAD_ADDRESS_FLASH;

//*----------------------------------------------------------------------------
//* \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,
						 AT91C_AIC_PRIOR_HIGHEST,
						 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)
{
	svcXmodem.tempo.Start(&(svcXmodem.tempo), 10, 0, AT91_XmodemComplete, svcXmodem.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()
{
	AT91PS_Buffer  		pXmBuffer;
	AT91PS_SvcComm 		pSvcXmodem;

	AT91F_DBGU_Printk("\n\n\r======================================================");
	AT91F_DBGU_Printk("\n\rAT91RM9200 Basic ROM Services BootLoader 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);

	/// Overload Xmodem Service
	svcXmodem.ReadHandler  = AT91F_SvcXmodemReadHandler_Overloaded;
	pSvcXmodem->pChild = &svcXmodem;

	// 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_LOWEST,
						 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\rSend the binary to write in DataFlash by Xmodem:\n\r");
	
	xmodemPipe.Read(&xmodemPipe, (char *) Buffer_Xmodem, MEMORY_SIZE_MAX, AT91_XmodemProtocol,NULL);
	while (EndOfTransmission != 1);
	EndOfTransmission =0;
	
	AT91F_DBGU_Printk("\n\rXmodem Transmission Completed !!!");
	AT91F_DBGU_Printk("\n\rCode Written in DataFlash ");
	AT91F_DBGU_Printk("at AT91C_BASE_LOAD_ADDRESS_FLASH\n\r");
					 
	while(1);
}

⌨️ 快捷键说明

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