Contiki 3.x
eeprom.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, IDentification Automation Laboratory
3  * IDALab (http://www.idalab.unisalento.it)
4  * Department of Innovation Engineering - University of Salento
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the Institute nor the names of its contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  */
33 
34 /**
35  * \file platform/mbxxx/dev/eeprom.c
36  * \brief ST M24C64W EEPROM driver.
37  * \author Maria Laura Stefanizzi <laura28582@gmail.com>
38  * \date 2013-11-20
39  */
40 
41 #include PLATFORM_HEADER
42 #include <dev/eeprom.h>
43 #include <dev/i2c.h>
44 
45 
46 #define EE_HW_ADDRESS 0xA0
47 #define EE_PAGESIZE 32
48 #define EE_PAGEMASK 0x1F
49 #define EE_MAX_TRIALS 300
50 
51 /* Write Cycle polling
52  *
53  * During the internal Write cycle, the device disconnects itself from the bus,
54  * and writes a copy of the data from its internal latches to the memory cells.
55  */
56 static inline void
57 eeprom_wait(void)
58 {
59  uint32_t trials = 0;
60 
61  /* Keep looping till the slave acknowledge his address or maximum number of
62  trials is reached */
63  do {
64  /* Generate start */
65  i2c_start();
66 
67  /* Device select in in write mode */
68  i2c_write(EE_HW_ADDRESS | 0x0);
69 
70  /* Check if the maximum allowed number of trials has been reached */
71  if(trials++ == EE_MAX_TRIALS) {
72  /* If the maximum number of trials has been reached, exit the function */
73  break;
74  }
75  } while((SC2_STAT(SC_TWIRXNAK)) == SC_TWIRXNAK);
76  /* eeprom reply with an ACK then it has terminated the internal Write cycle */
77 
78  i2c_stop();
79 }
80 
81 /**
82  * eeprom initializzation function
83  */
84 void
86 {
87  /* Nothing must be done here */
88 }
89 
90 /**
91  * Write data to eeprom
92  * @param addr The eeprom memory address
93  * @param buf It is the buffer of bytes that will be written to the eeprom
94  * @param size It is the number of byte to write
95  */
96 void
97 eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size)
98 {
99  unsigned int i = 0;
100  unsigned int curaddr;
101 
102  curaddr = addr;
103  for(i = 0; i < size; i++) {
104  /* If we are writing the first byte or are on a EE_PAGEMASK page boundary
105  we have to start a new write. */
106  if(i == 0 || (curaddr & EE_PAGEMASK) == 0) {
107 
108  i2c_start();
109  i2c_write(EE_HW_ADDRESS | 0x0);
110 
111  /* Write the new address to the bus. */
112  i2c_write((curaddr & 0xFF00) >> 8);
113  i2c_write(curaddr & 0xFF);
114  }
115 
116  /* Write byte. */
117  i2c_write(buf[i] & 0xFF);
118 
119  /* If we are writing the last byte totally or of a 32b page
120  generate a stop condition */
121  if(i == size - 1 || (curaddr & EE_PAGEMASK) == EE_PAGEMASK) {
122  i2c_stop();
123  eeprom_wait();
124  }
125 
126  curaddr++;
127  }
128 }
129 
130 /**
131  * Read data from eeprom
132  * @param addr The eeprom memory address
133  * @param buf It is the destination buffer in witch the bytes will be written
134  * @param size It is the number of byte to read
135  */
136 void
137 eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size)
138 {
139  uint8_t i;
140 
141  i2c_start();
142 
143  /* Select eeprom with write mode bit enabled */
144  i2c_write(EE_HW_ADDRESS | 0x0);
145 
146  /* Send address */
147  i2c_write((addr & 0xFF00) >> 8);
148  i2c_write(addr & 0xFF);
149 
150  i2c_start();
151 
152  /* Select eeprom with write mode bit disabled */
153  i2c_write(EE_HW_ADDRESS | 0x1);
154 
155  for(i = 0; i < size; i++) {
156  if(i < (size - 1)) {
157  /* Read data and send ACK */
158  *(buf + i) = i2c_read(1);
159  } else {
160  /* Last data, don't send ACK */
161  *(buf + i) = i2c_read(0);
162  }
163  }
164 
165  i2c_stop();
166 }
167 
168 /** @} */
void eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size)
Read data from the EEPROM.
Definition: eeprom.c:49
void i2c_write(uint8_t data)
Send a byte to I2C bus.
Definition: i2c.c:106
void i2c_stop(void)
Generate I2C STOP condition.
Definition: i2c.c:95
uint8_t i2c_read(int ack)
Read a byte from I2C bus.
Definition: i2c.c:121
void i2c_start(void)
Generate I2C START condition.
Definition: i2c.c:85
void eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size)
Write a buffer into EEPROM.
Definition: eeprom.c:42
EEPROM functions.
void eeprom_init(void)
Initialize the EEPROM module.
Definition: eeprom.c:72