📄 main.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 + -