199767f8919635c4928607450d9e0abb932109ceToomas Soome/******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Filename: eeprom.c
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Instantiation of eeprom routines
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Revision information:
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 28AUG2004 kb_admin initial creation - adapted from Atmel sources
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 12JAN2005 kb_admin fixed clock generation, write polling, init
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * BEGIN_KBDD_BLOCK
199767f8919635c4928607450d9e0abb932109ceToomas Soome * No warranty, expressed or implied, is included with this software. It is
199767f8919635c4928607450d9e0abb932109ceToomas Soome * provided "AS IS" and no warranty of any kind including statutory or aspects
199767f8919635c4928607450d9e0abb932109ceToomas Soome * relating to merchantability or fitness for any purpose is provided. All
199767f8919635c4928607450d9e0abb932109ceToomas Soome * intellectual property rights of others is maintained with the respective
199767f8919635c4928607450d9e0abb932109ceToomas Soome * owners. This software is not copyrighted and is intended for reference
199767f8919635c4928607450d9e0abb932109ceToomas Soome * only.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * END_BLOCK
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * $FreeBSD$
199767f8919635c4928607450d9e0abb932109ceToomas Soome *****************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "at91rm9200_lowlevel.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "at91rm9200.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "lib.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "ee.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/******************************* GLOBALS *************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*********************** PRIVATE FUNCTIONS/DATA ******************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Use a macro to calculate the TWI clock generator value to save code space. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define AT91C_TWSI_CLOCK 100000
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define TWSI_EEPROM_ADDRESS 0x40
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2)
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8))
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*************************** GLOBAL FUNCTIONS ********************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * .KB_C_FN_DEFINITION_START
199767f8919635c4928607450d9e0abb932109ceToomas Soome * void InitEEPROM(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This global function initializes the EEPROM interface (TWI). Intended
199767f8919635c4928607450d9e0abb932109ceToomas Soome * to be called a single time.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * .KB_C_FN_DEFINITION_END
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid
199767f8919635c4928607450d9e0abb932109ceToomas SoomeEEInit(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
199767f8919635c4928607450d9e0abb932109ceToomas Soome AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome pPio->PIO_ASR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
199767f8919635c4928607450d9e0abb932109ceToomas Soome pPio->PIO_PDR = AT91C_PIO_PA25 | AT91C_PIO_PA26;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome pPio->PIO_MDDR = ~AT91C_PIO_PA25;
199767f8919635c4928607450d9e0abb932109ceToomas Soome pPio->PIO_MDER = AT91C_PIO_PA25;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_IDR = 0xffffffffu;
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_CR = AT91C_TWI_SWRST;
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_CWGR = SET_TWI_CLOCK;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic inline unsigned
199767f8919635c4928607450d9e0abb932109ceToomas Soomeiicaddr(unsigned ee_off)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (TWSI_EEPROM_ADDRESS | ((ee_off >> 8) & 0x7));
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * .KB_C_FN_DEFINITION_START
199767f8919635c4928607450d9e0abb932109ceToomas Soome * void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This global function reads data from the eeprom at ee_addr storing data
199767f8919635c4928607450d9e0abb932109ceToomas Soome * to data_addr for size bytes. Assume the TWI has been initialized.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This function does not utilize the page read mode to simplify the code.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * .KB_C_FN_DEFINITION_END
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid
199767f8919635c4928607450d9e0abb932109ceToomas SoomeEERead(unsigned ee_off, char *data_addr, unsigned size)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned int status;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((ee_off & ~0xff) != ((ee_off + size) & ~0xff)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Crosses page boundary: 0x%x 0x%x\n", ee_off, size);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome status = twiPtr->TWI_SR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome status = twiPtr->TWI_RHR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) | AT91C_TWI_IADRSZ_1_BYTE |
199767f8919635c4928607450d9e0abb932109ceToomas Soome AT91C_TWI_MREAD;
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_IADR = ee_off & 0xff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_CR = AT91C_TWI_START;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (size-- > 1) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
199767f8919635c4928607450d9e0abb932109ceToomas Soome continue;
199767f8919635c4928607450d9e0abb932109ceToomas Soome *(data_addr++) = twiPtr->TWI_RHR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_CR = AT91C_TWI_STOP;
199767f8919635c4928607450d9e0abb932109ceToomas Soome status = twiPtr->TWI_SR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
199767f8919635c4928607450d9e0abb932109ceToomas Soome continue;
199767f8919635c4928607450d9e0abb932109ceToomas Soome *data_addr = twiPtr->TWI_RHR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * .KB_C_FN_DEFINITION_START
199767f8919635c4928607450d9e0abb932109ceToomas Soome * void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This global function writes data to the eeprom at ee_off using data
199767f8919635c4928607450d9e0abb932109ceToomas Soome * from data_addr for size bytes. Assume the TWI has been initialized.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This function does not utilize the page write mode as the write time is
199767f8919635c4928607450d9e0abb932109ceToomas Soome * much greater than the time required to access the device for byte-write
199767f8919635c4928607450d9e0abb932109ceToomas Soome * functionality. This allows the function to be much simpler.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * .KB_C_FN_DEFINITION_END
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid
199767f8919635c4928607450d9e0abb932109ceToomas SoomeEEWrite(unsigned ee_off, const char *data_addr, unsigned size)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned status;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char test_data;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (size--) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome // Set the TWI Master Mode Register
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) |
199767f8919635c4928607450d9e0abb932109ceToomas Soome AT91C_TWI_IADRSZ_1_BYTE;
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_IADR = ee_off++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome status = twiPtr->TWI_SR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome // Load one data byte
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_THR = *(data_addr++);
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_CR = AT91C_TWI_START;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY))
199767f8919635c4928607450d9e0abb932109ceToomas Soome continue;
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiPtr->TWI_CR = AT91C_TWI_STOP;
199767f8919635c4928607450d9e0abb932109ceToomas Soome status = twiPtr->TWI_SR;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
199767f8919635c4928607450d9e0abb932109ceToomas Soome continue;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome // wait for write operation to complete, it is done once
199767f8919635c4928607450d9e0abb932109ceToomas Soome // we can read it back...
199767f8919635c4928607450d9e0abb932109ceToomas Soome EERead(ee_off, &test_data, 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome}