📄 main.c
字号:
// Include Standard LIB files
#include "AT91SAM7X-EK.h"
#include "include/AT91SAM7X256.h"
#include "include/lib_AT91SAM7X256.h"
#define AT91_BAUD_RATE 115200
#define WAIT_TIME AT91B_MCK
#define AT91C_TWI_CLOCK 330000
#define AT91C_EEPROM_I2C_ADDRESS (0x50<<16)
#define MCK 48000000
#define ERROR (AT91C_TWI_NACK)
#define EEPROM_TEST_ADDRESS 0x00
#define USART0_INTERRUPT_LEVEL 6
#define USART1_INTERRUPT_LEVEL 7
static const char szembed_header[]=
{
"\n\r================================================"
"\n\r== Test IIC EEPROM Program =="
"\n\r================================================\n\r"
};
volatile int loop;
char value_write[2]={0};
char value_read[2]={'Y','Y'};
unsigned char value_write_flag=0x00;
//*--------------------------------------------------------------------------------------
//* Function Name : wait
//* Object : Software waiting loop
//* Input Parameters : none. Waiting time is defined by the global variable LedSpeed.
//* Output Parameters : none
//*--------------------------------------------------------------------------------------
void wait ( void )
{
//Wait at least 10 ms before value is written into EEPROM
for (loop=0; loop<10000; loop++){};
}
//*----------------------------------------------------------------------------
//* Function Name : delay
//* Object : Wait
//* Input Parameters : none
//* Output Parameters : none
//* Functions calAT91B_LED : none
//*----------------------------------------------------------------------------
void delay ( void )
{
//* Set in Volatile for Optimisation
volatile unsigned int i ;
//* loop delay
for ( i = 0 ;(i < WAIT_TIME/50 );i++ ) ;
}
//*----------------------------------------------------------------------------
//* Function Name : Usart_c_irq_handler
//* Object : C handler interrupt function
//* Input Parameters : none
//* Output Parameters : none
//*----------------------------------------------------------------------------
void Usart_c_irq_handler(void)
{
char status;
AT91PS_USART COM0 = AT91C_BASE_US0;
//* get Usart status register
status = COM0->US_CSR;
if ( status & AT91C_US_RXRDY)
{
//* Get byte to write to eeprom
value_write[0]=AT91F_US_GetChar(COM0);
AT91F_US_PutChar(COM0,value_write[0]);
value_write_flag=0x01;
}
//* Check error
if ( status & AT91C_US_FRAME)
{
AT91F_US_PutChar (COM0, 'F');
}
//* Reset the satus bit
COM0 ->US_CR = AT91C_US_RSTSTA;
}
//*----------------------------------------------------------------------------
//* Function Name : Usart_init
//* Object : USART initialization
//* Input Parameters : none
//* Output Parameters : TRUE
//*----------------------------------------------------------------------------
void Usart_init ( void )
{
AT91PS_USART COM0 = AT91C_BASE_US0;
// First, enable the clock of the USART
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_US0 ) ;
//* Configure PIO controllers to periph mode
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA,
((unsigned int) AT91C_PA0_RXD0 ) |
((unsigned int) AT91C_PA1_TXD0 ) |
((unsigned int) AT91C_PA3_RTS0 ) |
((unsigned int) AT91C_PA4_CTS0 ), // Peripheral A
0); // Peripheral B
// Usart Configure
AT91F_US_Configure (COM0, AT91B_MCK, AT91C_US_ASYNC_MODE, AT91_BAUD_RATE, 0);
// Enable usart
COM0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
//* Enable USART IT error and RXRDY
AT91F_US_EnableIt(COM0, AT91C_US_FRAME | AT91C_US_RXRDY);
//* open Usart 0 interrupt
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_US0, USART0_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, Usart_c_irq_handler);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);
AT91F_US_SendFrame(COM0,(char *)szembed_header,sizeof(szembed_header),0,0);
}
//*=========================================================
//* INIT
//*=========================================================
//*----------------------------------------------------------------------------
//* \fn AT91F_SetTwiClock
//* \brief Initialization
//*----------------------------------------------------------------------------
void AT91F_SetTwiClock(void)
{
int sclock;
/* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6)*/
sclock = (10*MCK /AT91C_TWI_CLOCK);
if (sclock % 10 >= 5)
sclock = (sclock /10) - 5;
else
sclock = (sclock /10)- 6;
sclock = (sclock + (4 - sclock %4)) >> 2; // div 4
AT91C_BASE_TWI->TWI_CWGR = ( 1<<16 ) | (sclock << 8) | sclock ;
}
//*=========================================================
//* WRITE
//*=========================================================
//*----------------------------------------------------------------------------
//* \fn AT91F_TWI_WriteByte
//* \brief Send a byte to a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_WriteByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2send, int nb)
{
unsigned int status,error=0;
// unsigned int counter=0;
// Set TWI Internal Address Register
if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;
// Set the TWI Master Mode Register
pTwi->TWI_MMR = mode & ~AT91C_TWI_MREAD;
// nb = 1 Byte Write mod, nb > 2 Page Write mod
if(nb <2){
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;
pTwi->TWI_THR = *data2send;
}
/*
else{
unsigned int p,d; // p: page number, d: data offset in page
d = nb%0x10;
p = (unsigned int)(nb/0x10);
if(p<=0){
AT91F_DBGU_Printk("\n\rwrite in the same page");
// Set the TWI Master Mode Register
for(counter=0;counter<nb;counter++){
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXRDY)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
pTwi->TWI_THR = *(data2send+counter);
}
}
else if(p>0){
unsigned int j;
AT91F_DBGU_Printk("\n\rwrite more then one page");
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
for(j=0; j<=p; j++){
// pTwi->TWI_MMR = 0x500100 | (j << 16);//select the page 0 - p
pTwi->TWI_IADR = int_address;
// uprintf("\n\r0x%x\n\r",pTwi->TWI_MMR);
for(counter=0;counter<16;counter++){
if ((counter == (16 - 1))&&(d == 0)&&(j > p)) pTwi->TWI_CR = AT91C_TWI_STOP;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXRDY)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}// end while (!(status & AT91C_TWI_TXRDY))
pTwi->TWI_THR = *(data2send+counter);
} //for(counter=0;counter<nb;counter++)
} //for(j=0; j<=p; j++)
//write the last page data number is d
pTwi->TWI_IADR = int_address;
for(counter=0;counter<d;counter++){
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
if (counter == (d - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXRDY)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
pTwi->TWI_THR = *(data2send+counter);
}
} // else if(p>0)
}
*/
// check SR register
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXCOMP)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
return error;
}
//*=========================================================
//* READ
//*=========================================================
//*----------------------------------------------------------------------------
//* \fn AT91F_TWI_ReadByte
//* \brief Read a byte from a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_ReadByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data, int nb)
{
unsigned int status,error=0;
// unsigned int counter=0;
// Set TWI Internal Address Register
if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;
// Set the TWI Master Mode Register
pTwi->TWI_MMR = mode | AT91C_TWI_MREAD;
// Start transfer
if (nb == 1){
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXCOMP)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
*(data) = pTwi->TWI_RHR;
}
/*
else{
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
// Wait transfer is finished
while (!(status & AT91C_TWI_TXCOMP)){
status = pTwi->TWI_SR;
if ((status & ERROR )== ERROR) error++;
if(status & AT91C_TWI_RXRDY){
*(data+counter++) = pTwi->TWI_RHR;
if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
}
}
}
*/
return error;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_TWI_Open
//* \brief Initializes TWI device
//*----------------------------------------------------------------------------
void AT91F_TWI_Open(void)
{
// Configure TWI PIOs
AT91F_TWI_CfgPIO ();
// Configure PMC by enabling TWI clock
AT91F_TWI_CfgPMC ();
// Configure TWI in master mode
AT91F_TWI_Configure (AT91C_BASE_TWI);
// Set TWI Clock Waveform Generator Register
AT91F_SetTwiClock();
}
//*----------------------------------------------------------------------------
//* Function Name : main
//* Object : Main interrupt function
//* Input Parameters : none
//* Output Parameters : TRUE
//*----------------------------------------------------------------------------
int main( void )
{
char status;
AT91PS_USART COM0 = AT91C_BASE_US0;
Usart_init();
// Enable User Reset and set its minimal assertion to 960 us
AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24);
//open port
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA );
//Initializes TWI device
AT91F_TWI_Open();
while(1)
{
if(value_write_flag==0x01)
{
delay();
// Write a byte
status = AT91F_TWI_WriteByte(AT91C_BASE_TWI, AT91C_EEPROM_I2C_ADDRESS | AT91C_TWI_IADRSZ_1_BYTE, EEPROM_TEST_ADDRESS, value_write, 1);
// Wait 10 ms before data is written into EEPROM
wait();
// Read a byte
status = AT91F_TWI_ReadByte(AT91C_BASE_TWI, AT91C_EEPROM_I2C_ADDRESS | AT91C_TWI_IADRSZ_1_BYTE ,EEPROM_TEST_ADDRESS, value_read, 1);
wait();
AT91F_US_PutChar(COM0,'<');
wait();
AT91F_US_PutChar(COM0,value_read[0]);
wait();
AT91F_US_PutChar(COM0,'>');
value_write_flag=0x00;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -