📄 eeprom.c
字号:
/*******************************************************************************
*
* Filename: eeprom.c
*
* Instantiation of eeprom routines
*
* Revision information:
*
* 28AUG2004 kb_admin initial creation - adapted from Atmel sources
*
* BEGIN_KBDD_BLOCK
* No warranty, expressed or implied, is included with this software. It is
* provided "AS IS" and no warranty of any kind including statutory or aspects
* relating to merchantability or fitness for any purpose is provided. All
* intellectual property rights of others is maintained with the respective
* owners. This software is not copyrighted and is intended for reference
* only.
* END_BLOCK
******************************************************************************/
#include "at91rm9200_lowlevel.h"
#include "eeprom.h"
#include "AT91RM9200.h"
/* ****************************** GLOBALS *************************************/
/* ********************** PRIVATE FUNCTIONS/DATA ******************************/
/* Use a macro to calculate the TWI clock generator value to save code space. */
#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(2*AT91C_TWSI_CLOCK)) - 2)
#define SET_TWI_CLOCK ((0x0001000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8))
/*
* .KB_C_FN_DEFINITION_START
* void SetTWIClock(const AT91PS_TWI twiPtr)
* This private function configures the clock used in TWI transactions.
* .KB_C_FN_DEFINITION_END
*/
static void SetTWIClock(const AT91PS_TWI twiPtr) {
twiPtr->TWI_CWGR = SET_TWI_CLOCK;
}
/* ************************** GLOBAL FUNCTIONS ********************************/
/*
* .KB_C_FN_DEFINITION_START
* void WriteEEPROM(unsigned ee_addr, char *data_addr, unsigned size)
* This global function writes data to the eeprom at ee_addr using data
* from data_addr for size bytes.
* .KB_C_FN_DEFINITION_END
*/
void WriteEEPROM(unsigned ee_addr, char *data_addr, unsigned size) {
static unsigned initialized = 0;
const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
unsigned status, useLength;
if (!initialized) {
AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
initialized = 1;
pPio->PIO_ASR =
((unsigned)AT91C_PA25_TWD) | ((unsigned)AT91C_PA26_TWCK);
pPio->PIO_BSR = 0;
pPio->PIO_PDR =
((unsigned)AT91C_PA25_TWD) | ((unsigned)AT91C_PA26_TWCK);
pPio->PIO_MDDR = ~((unsigned)AT91C_PA25_TWD);
pPio->PIO_MDER = (unsigned)AT91C_PA25_TWD;
pPMC->PMC_PCER = ((unsigned) 1 << AT91C_ID_TWI);
twiPtr->TWI_IDR = (unsigned) -1;
twiPtr->TWI_CR = AT91C_TWI_SWRST;
twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;
SetTWIClock(AT91C_BASE_TWI);
}
while (size) {
DebugPrint(".");
useLength = ee_addr & (EEPROM_PAGE_SIZE - 1);
useLength = EEPROM_PAGE_SIZE - useLength;
if (useLength > size)
useLength = size;
size -= useLength;
// Set the TWI Master Mode Register
twiPtr->TWI_MMR = ((TWSI_EEPROM_ADDRESS << 16) | AT91C_TWI_IADRSZ_2_BYTE ) & ~AT91C_TWI_MREAD;
// Set TWI Internal Address Register
twiPtr->TWI_IADR = ee_addr;
ee_addr += useLength;
status = twiPtr->TWI_SR;
twiPtr->TWI_THR = *(data_addr++);
twiPtr->TWI_CR = AT91C_TWI_START;
while (useLength-- > 1) {
// Wait THR Holding register to be empty
while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY));
// Send first byte
twiPtr->TWI_THR = *(data_addr++);
}
twiPtr->TWI_CR = AT91C_TWI_STOP;
status = twiPtr->TWI_SR;
// Wait transfer is finished
while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP));
// delay loop - could convert to ack polling method
for (useLength = 100000; useLength; useLength--);
}
DebugPrint("\n\r");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -