eeprom.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:23k
- /*!*****************************************************************************
- *!
- *! Implements an interface for i2c compatible eeproms to run under linux.
- *! Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by
- *! Johan.Adolfsson@axis.com
- *!
- *! Probing results:
- *! 8k or not is detected (the assumes 2k or 16k)
- *! 2k or 16k detected using test reads and writes.
- *!
- *!------------------------------------------------------------------------
- *! HISTORY
- *!
- *! DATE NAME CHANGES
- *! ---- ---- -------
- *! Aug 28 1999 Edgar Iglesias Initial Version
- *! Aug 31 1999 Edgar Iglesias Allow simultaneous users.
- *! Sep 03 1999 Edgar Iglesias Updated probe.
- *! Sep 03 1999 Edgar Iglesias Added bail-out stuff if we get interrupted
- *! in the spin-lock.
- *!
- *! $Log: eeprom.c,v $
- *! Revision 1.8 2001/06/15 13:24:29 jonashg
- *! * Added verification of pointers from userspace in read and write.
- *! * Made busy counter volatile.
- *! * Added define for inital write delay.
- *! * Removed warnings by using loff_t instead of unsigned long.
- *!
- *! Revision 1.7 2001/06/14 15:26:54 jonashg
- *! Removed test because condition is always true.
- *!
- *! Revision 1.6 2001/06/14 15:18:20 jonashg
- *! Kb -> kB (makes quite a difference if you don't know if you have 2k or 16k).
- *!
- *! Revision 1.5 2001/06/14 14:39:51 jonashg
- *! Forgot to use name when registering the driver.
- *!
- *! Revision 1.4 2001/06/14 14:35:47 jonashg
- *! * Gave driver a name and used it in printk's.
- *! * Cleanup.
- *!
- *! Revision 1.3 2001/03/19 16:04:46 markusl
- *! Fixed init of fops struct
- *!
- *! Revision 1.2 2001/03/19 10:35:07 markusl
- *! 2.4 port of eeprom driver
- *!
- *! Revision 1.8 2000/05/18 10:42:25 edgar
- *! Make sure to end write cycle on _every_ write
- *!
- *! Revision 1.7 2000/01/17 17:41:01 johana
- *! Adjusted probing and return -ENOSPC when writing outside EEPROM
- *!
- *! Revision 1.6 2000/01/17 15:50:36 johana
- *! Added adaptive timing adjustments and fixed autoprobing for 2k and 16k(?)
- *! EEPROMs
- *!
- *! Revision 1.5 1999/09/03 15:07:37 edgar
- *! Added bail-out check to the spinlock
- *!
- *! Revision 1.4 1999/09/03 12:11:17 bjornw
- *! Proper atomicity (need to use spinlocks, not if's). users -> busy.
- *!
- *!
- *! (c) 1999 Axis Communications AB, Lund, Sweden
- *!*****************************************************************************/
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
- #include <linux/fs.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <asm/uaccess.h>
- #include "i2c.h"
- #define D(x)
- /* If we should use adaptive timing or not: */
- //#define EEPROM_ADAPTIVE_TIMING
- #define EEPROM_MAJOR_NR 122 /* use a LOCAL/EXPERIMENTAL major for now */
- #define EEPROM_MINOR_NR 0
- /* Empirical sane initial value of the delay, the value will be adapted to
- * what the chip needs when using EEPROM_ADAPTIVE_TIMING.
- */
- #define INITIAL_WRITEDELAY_US 4000
- #define MAX_WRITEDELAY_US 10000 /* 10 ms according to spec for 2KB EEPROM */
- /* This one defines how many times to try when eeprom fails. */
- #define EEPROM_RETRIES 10
- #define EEPROM_2KB (2 * 1024)
- /*#define EEPROM_4KB (4 * 1024)*/ /* Exists but not used in Axis products */
- #define EEPROM_8KB (8 * 1024 - 1 ) /* Last byte has write protection bit */
- #define EEPROM_16KB (16 * 1024)
- #define i2c_delay(x) udelay(x)
- /*
- * This structure describes the attached eeprom chip.
- * The values are probed for.
- */
- struct eeprom_type
- {
- unsigned long size;
- unsigned long sequential_write_pagesize;
- unsigned char select_cmd;
- unsigned long usec_delay_writecycles; /* Min time between write cycles
- (up to 10ms for some models) */
- unsigned long usec_delay_step; /* For adaptive algorithm */
- int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */
-
- /* this one is to keep the read/write operations atomic */
- wait_queue_head_t wait_q;
- volatile int busy;
- int retry_cnt_addr; /* Used to keep track of number of retries for
- adaptive timing adjustments */
- int retry_cnt_read;
- };
- static int eeprom_open(struct inode * inode, struct file * file);
- static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig);
- static ssize_t eeprom_read(struct file * file, char * buf, size_t count,
- loff_t *off);
- static ssize_t eeprom_write(struct file * file, const char * buf, size_t count,
- loff_t *off);
- static int eeprom_close(struct inode * inode, struct file * file);
- static int eeprom_address(unsigned long addr);
- static int read_from_eeprom(char * buf, int count);
- static int eeprom_write_buf(loff_t addr, const char * buf, int count);
- static int eeprom_read_buf(loff_t addr, char * buf, int count);
- static void eeprom_disable_write_protect(void);
- static const char eeprom_name[] = "eeprom";
- /* chip description */
- static struct eeprom_type eeprom;
- /* This is the exported file-operations structure for this device. */
- struct file_operations eeprom_fops =
- {
- llseek: eeprom_lseek,
- read: eeprom_read,
- write: eeprom_write,
- open: eeprom_open,
- release: eeprom_close
- };
- /* eeprom init call. Probes for different eeprom models. */
- int __init eeprom_init(void)
- {
- init_waitqueue_head(&eeprom.wait_q);
- eeprom.busy = 0;
- #if CONFIG_ETRAX_I2C_EEPROM_PROBE
- #define EETEXT "Found"
- #else
- #define EETEXT "Assuming"
- #endif
- if (register_chrdev(EEPROM_MAJOR_NR, eeprom_name, &eeprom_fops))
- {
- printk(KERN_INFO "%s: unable to get major %d for eeprom devicen",
- eeprom_name, EEPROM_MAJOR_NR);
- return -1;
- }
-
- printk("EEPROM char device v0.3, (c) 2000 Axis Communications ABn");
- /*
- * Note: Most of this probing method was taken from the printserver (5470e)
- * codebase. It did not contain a way of finding the 16kB chips
- * (M24128 or variants). The method used here might not work
- * for all models. If you encounter problems the easiest way
- * is probably to define your model within #ifdef's, and hard-
- * code it.
- */
- eeprom.size = 0;
- eeprom.usec_delay_writecycles = INITIAL_WRITEDELAY_US;
- eeprom.usec_delay_step = 128;
- eeprom.adapt_state = 0;
-
- #if CONFIG_ETRAX_I2C_EEPROM_PROBE
- i2c_start();
- i2c_outbyte(0x80);
- if(!i2c_getack())
- {
- /* It's not 8k.. */
- int success = 0;
- unsigned char buf_2k_start[16];
-
- /* Im not sure this will work... :) */
- /* assume 2kB, if failure go for 16kB */
- /* Test with 16kB settings.. */
- /* If it's a 2kB EEPROM and we address it outside it's range
- * it will mirror the address space:
- * 1. We read two locations (that are mirrored),
- * if the content differs * it's a 16kB EEPROM.
- * 2. if it doesn't differ - write diferent value to one of the locations,
- * check the other - if content still is the same it's a 2k EEPROM,
- * restore original data.
- */
- #define LOC1 8
- #define LOC2 (0x1fb) /*1fb, 3ed, 5df, 7d1 */
- /* 2k settings */
- i2c_stop();
- eeprom.size = EEPROM_2KB;
- eeprom.select_cmd = 0xA0;
- eeprom.sequential_write_pagesize = 16;
- if( eeprom_read_buf( 0, buf_2k_start, 16 ) == 16 )
- {
- D(printk("2k start: '%16.16s'n", buf_2k_start));
- }
- else
- {
- printk(KERN_INFO "%s: Failed to read in 2k mode!n", eeprom_name);
- }
-
- /* 16k settings */
- eeprom.size = EEPROM_16KB;
- eeprom.select_cmd = 0xA0;
- eeprom.sequential_write_pagesize = 64;
- {
- unsigned char loc1[4], loc2[4], tmp[4];
- if( eeprom_read_buf(LOC2, loc2, 4) == 4)
- {
- if( eeprom_read_buf(LOC1, loc1, 4) == 4)
- {
- D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'n",
- LOC1, loc1, LOC2, loc2));
- #if 0
- if (memcmp(loc1, loc2, 4) != 0 )
- {
- /* It's 16k */
- printk(KERN_INFO "%s: 16k detected in step 1n", eeprom_name);
- eeprom.size = EEPROM_16KB;
- success = 1;
- }
- else
- #endif
- {
- /* Do step 2 check */
- /* Invert value */
- loc1[0] = ~loc1[0];
- if (eeprom_write_buf(LOC1, loc1, 1) == 1)
- {
- /* If 2k EEPROM this write will actually write 10 bytes
- * from pos 0
- */
- D(printk("1 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'n",
- LOC1, loc1, LOC2, loc2));
- if( eeprom_read_buf(LOC1, tmp, 4) == 4)
- {
- D(printk("2 loc1: (%i) '%4.4s' tmp '%4.4s'n",
- LOC1, loc1, tmp));
- if (memcmp(loc1, tmp, 4) != 0 )
- {
- printk(KERN_INFO "%s: read and write differs! Not 16kBn",
- eeprom_name);
- loc1[0] = ~loc1[0];
-
- if (eeprom_write_buf(LOC1, loc1, 1) == 1)
- {
- success = 1;
- }
- else
- {
- printk(KERN_INFO "%s: Restore 2k failed during probe,"
- " EEPROM might be corrupt!n", eeprom_name);
-
- }
- i2c_stop();
- /* Go to 2k mode and write original data */
- eeprom.size = EEPROM_2KB;
- eeprom.select_cmd = 0xA0;
- eeprom.sequential_write_pagesize = 16;
- if( eeprom_write_buf(0, buf_2k_start, 16) == 16)
- {
- }
- else
- {
- printk(KERN_INFO "%s: Failed to write back 2k start!n",
- eeprom_name);
- }
-
- eeprom.size = EEPROM_2KB;
- }
- }
-
- if(!success)
- {
- if( eeprom_read_buf(LOC2, loc2, 1) == 1)
- {
- D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'n",
- LOC1, loc1, LOC2, loc2));
- if (memcmp(loc1, loc2, 4) == 0 )
- {
- /* Data the same, must be mirrored -> 2k */
- /* Restore data */
- printk(KERN_INFO "%s: 2k detected in step 2n", eeprom_name);
- loc1[0] = ~loc1[0];
- if (eeprom_write_buf(LOC1, loc1, 1) == 1)
- {
- success = 1;
- }
- else
- {
- printk(KERN_INFO "%s: Restore 2k failed during probe,"
- " EEPROM might be corrupt!n", eeprom_name);
-
- }
-
- eeprom.size = EEPROM_2KB;
- }
- else
- {
- printk(KERN_INFO "%s: 16k detected in step 2n",
- eeprom_name);
- loc1[0] = ~loc1[0];
- /* Data differs, assume 16k */
- /* Restore data */
- if (eeprom_write_buf(LOC1, loc1, 1) == 1)
- {
- success = 1;
- }
- else
- {
- printk(KERN_INFO "%s: Restore 16k failed during probe,"
- " EEPROM might be corrupt!n", eeprom_name);
- }
-
- eeprom.size = EEPROM_16KB;
- }
- }
- }
- }
- } /* read LOC1 */
- } /* address LOC1 */
- if (!success)
- {
- printk(KERN_INFO "%s: Probing failed!, using 2KB!n", eeprom_name);
- eeprom.size = EEPROM_2KB;
- }
- } /* read */
- }
- }
- else
- {
- i2c_outbyte(0x00);
- if(!i2c_getack())
- {
- /* No 8k */
- eeprom.size = EEPROM_2KB;
- }
- else
- {
- i2c_start();
- i2c_outbyte(0x81);
- if (!i2c_getack())
- {
- eeprom.size = EEPROM_2KB;
- }
- else
- {
- /* It's a 8kB */
- i2c_inbyte();
- eeprom.size = EEPROM_8KB;
- }
- }
- }
- i2c_stop();
- #elif defined(CONFIG_ETRAX_I2C_EEPROM_16KB)
- eeprom.size = EEPROM_16KB;
- #elif defined(CONFIG_ETRAX_I2C_EEPROM_8KB)
- eeprom.size = EEPROM_8KB;
- #elif defined(CONFIG_ETRAX_I2C_EEPROM_2KB)
- eeprom.size = EEPROM_2KB;
- #endif
- switch(eeprom.size)
- {
- case (EEPROM_2KB):
- printk("%s: " EETEXT " i2c compatible 2kB eeprom.n", eeprom_name);
- eeprom.sequential_write_pagesize = 16;
- eeprom.select_cmd = 0xA0;
- break;
- case (EEPROM_8KB):
- printk("%s: " EETEXT " i2c compatible 8kB eeprom.n", eeprom_name);
- eeprom.sequential_write_pagesize = 16;
- eeprom.select_cmd = 0x80;
- break;
- case (EEPROM_16KB):
- printk("%s: " EETEXT " i2c compatible 16kB eeprom.n", eeprom_name);
- eeprom.sequential_write_pagesize = 64;
- eeprom.select_cmd = 0xA0;
- break;
- default:
- eeprom.size = 0;
- printk("%s: Did not find a supported eepromn", eeprom_name);
- break;
- }
-
- eeprom_disable_write_protect();
- return 0;
- }
- /* Opens the device. */
- static int eeprom_open(struct inode * inode, struct file * file)
- {
- if(MINOR(inode->i_rdev) != EEPROM_MINOR_NR)
- return -ENXIO;
- if(MAJOR(inode->i_rdev) != EEPROM_MAJOR_NR)
- return -ENXIO;
- if( eeprom.size > 0 )
- {
- /* OK */
- return 0;
- }
- /* No EEprom found */
- return -EFAULT;
- }
- /* Changes the current file position. */
- static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
- {
- /*
- * orig 0: position from begning of eeprom
- * orig 1: relative from current position
- * orig 2: position from last eeprom address
- */
-
- switch (orig)
- {
- case 0:
- file->f_pos = offset;
- break;
- case 1:
- file->f_pos += offset;
- break;
- case 2:
- file->f_pos = eeprom.size - offset;
- break;
- default:
- return -EINVAL;
- }
- /* truncate position */
- if (file->f_pos < 0)
- {
- file->f_pos = 0;
- return(-EOVERFLOW);
- }
-
- if (file->f_pos >= eeprom.size)
- {
- file->f_pos = eeprom.size - 1;
- return(-EOVERFLOW);
- }
- return ( file->f_pos );
- }
- /* Reads data from eeprom. */
- static int eeprom_read_buf(loff_t addr, char * buf, int count)
- {
- struct file f;
- f.f_pos = addr;
- return eeprom_read(&f, buf, count, &addr);
- }
- /* Reads data from eeprom. */
- static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
- {
- int i, read=0;
- unsigned long p = file->f_pos;
- unsigned char page;
- if(p >= eeprom.size) /* Address i 0 - (size-1) */
- {
- return -EFAULT;
- }
-
- while(eeprom.busy)
- {
- interruptible_sleep_on(&eeprom.wait_q);
- /* bail out if we get interrupted */
- if (signal_pending(current))
- return -EINTR;
-
- }
- eeprom.busy++;
- page = (unsigned char) (p >> 8);
-
- if(!eeprom_address(p))
- {
- printk(KERN_INFO "%s: Read failed to address the eeprom: "
- "0x%08X (%i) page: %in", eeprom_name, p, p, page);
- i2c_stop();
-
- /* don't forget to wake them up */
- eeprom.busy--;
- wake_up_interruptible(&eeprom.wait_q);
- return -EFAULT;
- }
- if( (p + count) > eeprom.size)
- {
- /* truncate count */
- count = eeprom.size - p;
- }
- /* stop dummy write op and initiate the read op */
- i2c_start();
- /* special case for small eeproms */
- if(eeprom.size < EEPROM_16KB)
- {
- i2c_outbyte( eeprom.select_cmd | 1 | (page << 1) );
- }
- /* go on with the actual read */
- read = read_from_eeprom( buf, count);
-
- if(read > 0)
- {
- file->f_pos += read;
- }
- eeprom.busy--;
- wake_up_interruptible(&eeprom.wait_q);
- return read;
- }
- /* Writes data to eeprom. */
- static int eeprom_write_buf(loff_t addr, const char * buf, int count)
- {
- struct file f;
- f.f_pos = addr;
-
- return eeprom_write(&f, buf, count, &addr);
- }
- /* Writes data to eeprom. */
- static ssize_t eeprom_write(struct file * file, const char * buf, size_t count,
- loff_t *off)
- {
- int i, written, restart=1;
- unsigned long p;
- if (verify_area(VERIFY_READ, buf, count))
- {
- return -EFAULT;
- }
- while(eeprom.busy)
- {
- interruptible_sleep_on(&eeprom.wait_q);
- /* bail out if we get interrupted */
- if (signal_pending(current))
- return -EINTR;
- }
- eeprom.busy++;
- for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++)
- {
- restart = 0;
- written = 0;
- p = file->f_pos;
-
-
- while( (written < count) && (p < eeprom.size))
- {
- /* address the eeprom */
- if(!eeprom_address(p))
- {
- printk(KERN_INFO "%s: Write failed to address the eeprom: "
- "0x%08X (%i) n", eeprom_name, p, p);
- i2c_stop();
-
- /* don't forget to wake them up */
- eeprom.busy--;
- wake_up_interruptible(&eeprom.wait_q);
- return -EFAULT;
- }
- #ifdef EEPROM_ADAPTIVE_TIMING
- /* Adaptive algorithm to adjust timing */
- if (eeprom.retry_cnt_addr > 0)
- {
- /* To Low now */
- D(printk(">D=%i d=%in",
- eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
- if (eeprom.usec_delay_step < 4)
- {
- eeprom.usec_delay_step++;
- eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
- }
- else
- {
- if (eeprom.adapt_state > 0)
- {
- /* To Low before */
- eeprom.usec_delay_step *= 2;
- if (eeprom.usec_delay_step > 2)
- {
- eeprom.usec_delay_step--;
- }
- eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
- }
- else if (eeprom.adapt_state < 0)
- {
- /* To High before (toggle dir) */
- eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
- if (eeprom.usec_delay_step > 1)
- {
- eeprom.usec_delay_step /= 2;
- eeprom.usec_delay_step--;
- }
- }
- }
- eeprom.adapt_state = 1;
- }
- else
- {
- /* To High (or good) now */
- D(printk("<D=%i d=%in",
- eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
-
- if (eeprom.adapt_state < 0)
- {
- /* To High before */
- if (eeprom.usec_delay_step > 1)
- {
- eeprom.usec_delay_step *= 2;
- eeprom.usec_delay_step--;
-
- if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
- {
- eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
- }
- }
- }
- else if (eeprom.adapt_state > 0)
- {
- /* To Low before (toggle dir) */
- if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
- {
- eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
- }
- if (eeprom.usec_delay_step > 1)
- {
- eeprom.usec_delay_step /= 2;
- eeprom.usec_delay_step--;
- }
-
- eeprom.adapt_state = -1;
- }
- if (eeprom.adapt_state > -100)
- {
- eeprom.adapt_state--;
- }
- else
- {
- /* Restart adaption */
- D(printk("#Restartn"));
- eeprom.usec_delay_step++;
- }
- }
- #endif /* EEPROM_ADAPTIVE_TIMING */
- /* write until we hit a page boundary or count */
- do
- {
- i2c_outbyte(buf[written]);
- if(!i2c_getack())
- {
- restart=1;
- printk(KERN_INFO "%s: write error, retrying. %dn", eeprom_name, i);
- i2c_stop();
- break;
- }
- written++;
- p++;
- } while( written < count && ( p % eeprom.sequential_write_pagesize ));
- /* end write cycle */
- i2c_stop();
- i2c_delay(eeprom.usec_delay_writecycles);
- } /* while */
- } /* for */
- eeprom.busy--;
- wake_up_interruptible(&eeprom.wait_q);
- if (written == 0 && file->f_pos >= eeprom.size){
- return -ENOSPC;
- }
- file->f_pos += written;
- return written;
- }
- /* Closes the device. */
- static int eeprom_close(struct inode * inode, struct file * file)
- {
- /* do nothing for now */
- return 0;
- }
- /* Sets the current address of the eeprom. */
- static int eeprom_address(unsigned long addr)
- {
- int i, j;
- unsigned char page, offset;
- page = (unsigned char) (addr >> 8);
- offset = (unsigned char) addr;
- for(i = 0; i < EEPROM_RETRIES; i++)
- {
- /* start a dummy write for addressing */
- i2c_start();
- if(eeprom.size == EEPROM_16KB)
- {
- i2c_outbyte( eeprom.select_cmd );
- i2c_getack();
- i2c_outbyte(page);
- }
- else
- {
- i2c_outbyte( eeprom.select_cmd | (page << 1) );
- }
- if(!i2c_getack())
- {
- /* retry */
- i2c_stop();
- /* Must have a delay here.. 500 works, >50, 100->works 5th time*/
- i2c_delay(MAX_WRITEDELAY_US / EEPROM_RETRIES * i);
- /* The chip needs up to 10 ms from write stop to next start */
-
- }
- else
- {
- i2c_outbyte(offset);
-
- if(!i2c_getack())
- {
- /* retry */
- i2c_stop();
- }
- else
- break;
- }
- }
-
- eeprom.retry_cnt_addr = i;
- D(printk("%in", eeprom.retry_cnt_addr));
- if(eeprom.retry_cnt_addr == EEPROM_RETRIES)
- {
- /* failed */
- return 0;
- }
- return 1;
- }
- /* Reads from current adress. */
- static int read_from_eeprom(char * buf, int count)
- {
- int i, read=0;
- for(i = 0; i < EEPROM_RETRIES; i++)
- {
- if(eeprom.size == EEPROM_16KB)
- {
- i2c_outbyte( eeprom.select_cmd | 1 );
- }
- if(i2c_getack());
- {
- break;
- }
- }
-
- if(i == EEPROM_RETRIES)
- {
- printk(KERN_INFO "%s: failed to read from eepromn", eeprom_name);
- i2c_stop();
-
- return -EFAULT;
- }
- while( (read < count))
- {
- if (put_user(i2c_inbyte(), &buf[read++]))
- {
- i2c_stop();
- return -EFAULT;
- }
- /*
- * make sure we don't ack last byte or you will get very strange
- * results!
- */
- if(read < count)
- {
- i2c_sendack();
- }
- }
- /* stop the operation */
- i2c_stop();
- return read;
- }
- /* Disables write protection if applicable. */
- #define DBP_SAVE(x)
- #define ax_printf printk
- static void eeprom_disable_write_protect(void)
- {
- /* Disable write protect */
- if (eeprom.size == EEPROM_8KB)
- {
- /* Step 1 Set WEL = 1 (write 00000010 to address 1FFFh */
- i2c_start();
- i2c_outbyte(0xbe);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns falsen"));
- }
- i2c_outbyte(0xFF);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 2n"));
- }
- i2c_outbyte(0x02);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 3n"));
- }
- i2c_stop();
- i2c_delay(1000);
- /* Step 2 Set RWEL = 1 (write 00000110 to address 1FFFh */
- i2c_start();
- i2c_outbyte(0xbe);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 55n"));
- }
- i2c_outbyte(0xFF);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 52n"));
- }
- i2c_outbyte(0x06);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 53n"));
- }
- i2c_stop();
-
- /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh */
- i2c_start();
- i2c_outbyte(0xbe);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 56n"));
- }
- i2c_outbyte(0xFF);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 57n"));
- }
- i2c_outbyte(0x06);
- if(!i2c_getack())
- {
- DBP_SAVE(ax_printf("Get ack returns false 58n"));
- }
- i2c_stop();
-
- /* Write protect disabled */
- }
- }
- module_init(eeprom_init);