ARMEBS4  revision-26.06.2015
eeprom.c
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////
2 /// \file heivs/eeprom.c
3 /// \brief ARMEBS4 eeprom access functions
4 /// \author Pascal Sartoretti (sap at hevs dot ch)
5 //////////////////////////////////////////////////////////////////////////////////
6 #include "heivs/eeprom.h"
7 #include "heivs/stm32_i2c.h"
8 #include "heivs/delay.h"
9 
10 // address of I2C EEPROM 24LC64 mounted on ARMEBS4
11 #define ADDR_24LC64 0x50
12 #define PAGE_SIZE_24LC64 32U
13 #define SIZE_24LC64 8192U
14 
15 //////////////////////////////////////////////////////////////////////////////////
16 /// \brief Structure of the eeprom
17 //////////////////////////////////////////////////////////////////////////////////
18 #define MAGIC_NUMBER 0xAA55AA55
19 #define EEPROM_VERSION 0x00000100
20 
21 /**
22  * \brief EEPROM content
23  * \internal
24  */
26 {
27  uint32_t magic; ///< Magic number
28  uint32_t version; ///< Version of data
29  uint8_t unique_number;
30  uint8_t calib_valid;
31  uint8_t touch_calib[24];
32  uint8_t mac_address[6];
33 };
34 
35 static const struct heivs_bus_t *bus = &bus_i2c[0];
36 
37 //////////////////////////////////////////////////////////////////////////////////
38 /// \brief Read data from EEPROM for a given size
39 /// \param address Address in EEPROM to read
40 /// \param dst Pointer to data buffer to be filled by eeprom data
41 /// \param size Number of bytes to read
42 //////////////////////////////////////////////////////////////////////////////////
43 static status_e EEPROM_Read(uint16_t address, void * dst, size_t size)
44 {
45  status_e status;
46  uint8_t eeAddress[2];
47 
48  if((address + size) > SIZE_24LC64 -1)
49  {
50  return ERROR_BAD_PARAM;
51  }
52  eeAddress[0] = address >> 8;
53  eeAddress[1] = address;
54  status = bus_init(bus);
55  if(status != NO_ERROR) return status;
56  status = bus_get(bus);
57  if(status != NO_ERROR) return status;
58  status = bus_writeread(bus,ADDR_24LC64,eeAddress,2,dst,size,NULL);
59  if(status != NO_ERROR) return status;
60  status = bus_release(bus);
61  if(status != NO_ERROR) return status;
62 
63  return NO_ERROR;
64 }
65 //////////////////////////////////////////////////////////////////////////////////
66 /// \brief Write data in EEPROM for a given size
67 /// \param address Address in EEPROM to write
68 /// \param src Pointer to data buffer to write into eeprom
69 /// \param size Number of bytes to write
70 //////////////////////////////////////////////////////////////////////////////////
71 static status_e EEPROM_Write(uint16_t address, const void * src, size_t size)
72 {
73  status_e status;
74  uint8_t eePattern[PAGE_SIZE_24LC64 + 2];
75  uint16_t addressCounter = address;
76  size_t calcSize;
77  size_t remainingSize=size;
78 
79  if((address + size) > SIZE_24LC64 -1)
80  {
81  return ERROR_BAD_PARAM;
82  }
83  do
84  {
85  eePattern[0] = addressCounter >> 8;
86  eePattern[1] = addressCounter;
87  calcSize = min(PAGE_SIZE_24LC64 - (addressCounter & (PAGE_SIZE_24LC64-1)),remainingSize);
88  remainingSize -= calcSize;
89  addressCounter += calcSize;
90  memcpy(&eePattern[2],src,PAGE_SIZE_24LC64);
91  src += calcSize;
92  status = bus_init(bus);
93  if(status != NO_ERROR) return status;
94  status = bus_get(bus);
95  if(status != NO_ERROR) return status;
96  status = bus_write(bus,ADDR_24LC64,eePattern,calcSize+2);
97  if(status != NO_ERROR) return status;
98  status = bus_release(bus);
99  if(status != NO_ERROR) return status;
100  delay_wait_ms(5); // max delay to write one page
101  }while(addressCounter < (address + size));
102 
103  return NO_ERROR;
104 }
105 
106 static status_e EEPROM_Valid(struct eeprom_content_t *eeprom)
107 {
108  if (eeprom->magic != MAGIC_NUMBER)
109  {
110  return ERROR_EEPROM_BAD_MAGIC;
111  }
112 
113  // We could update the version if it didn't match
114  if (eeprom->version != EEPROM_VERSION)
115  {
116  return ERROR_EEPROM_BAD_MAGIC;
117  }
118 
119  return NO_ERROR;
120 }
121 
122 
124 {
125  struct eeprom_content_t eeprom;
126  status_e status;
127 
128  status = EEPROM_Read(0, &eeprom, sizeof(eeprom));
129  if(status != NO_ERROR)
130  {
131  return status;
132  }
133  status = EEPROM_Valid(&eeprom);
134  if(status != NO_ERROR)
135  {
136  return status;
137  }
138  *number = eeprom.unique_number;
139  return NO_ERROR;
140 }
141 
142 status_e EEPROM_Calib_Read(uint8_t calib[24])
143 {
144  struct eeprom_content_t eeprom;
145  status_e status;
146 
147  status = EEPROM_Read(0, &eeprom, sizeof(eeprom));
148  if(status != NO_ERROR)
149  {
150  return status;
151  }
152  status = EEPROM_Valid(&eeprom);
153  if(status != NO_ERROR)
154  {
155  return status;
156  }
157  if(eeprom.calib_valid != sizeof(eeprom.touch_calib))
158  {
159  return ERROR_EEPROM_BAD_CALIB;
160  }
161  memcpy(calib,&eeprom.touch_calib,sizeof(eeprom.touch_calib));
162  return NO_ERROR;
163 }
164 
166 {
167  struct eeprom_content_t eeprom;
168  status_e status;
169 
170  status = EEPROM_Read(0, &eeprom, sizeof(eeprom));
171  if(status != NO_ERROR)
172  {
173  return status;
174  }
175  status = EEPROM_Valid(&eeprom);
176  if(status != NO_ERROR)
177  {
178  return status;
179  }
180 
181  memcpy(mac,&eeprom.mac_address,sizeof(eeprom.mac_address));
182 
183  return NO_ERROR;
184 }
185 
186 status_e EEPROM_Calib_Write(const uint8_t calib[24])
187 {
188  struct eeprom_content_t eeprom;
189  status_e status;
190 
191  status = EEPROM_Read(0, &eeprom, sizeof(eeprom));
192  if(status != NO_ERROR)
193  {
194  return status;
195  }
196  status = EEPROM_Valid(&eeprom);
197  if(status != NO_ERROR)
198  {
199  return status;
200  }
201 
202  if (calib)
203  {
204  eeprom.calib_valid = sizeof(eeprom.touch_calib);
205  memcpy(&eeprom.touch_calib,calib,sizeof(eeprom.touch_calib));
206  }
207  else
208  {
209  eeprom.calib_valid = 0;
210  }
211 
212  status = EEPROM_Write(0, &eeprom, sizeof(eeprom));
213  return status;
214 }
215 
216 status_e EEPROM_FirstInit(uint8_t number, uint8_t * macAddr)
217 {
218  struct eeprom_content_t eeprom;
219  status_e status;
220 
221  if (!number || !macAddr)
222  {
223  return ERROR_BAD_PARAM;
224  }
225 
226  memset(&eeprom, 0x0, sizeof(eeprom));
227 
228  eeprom.magic = MAGIC_NUMBER;
229  eeprom.version = EEPROM_VERSION;
230  eeprom.calib_valid = 0; // force calibration
231  eeprom.unique_number = number;
232  memcpy(&eeprom.mac_address, macAddr, sizeof(eeprom.mac_address));
233  status = EEPROM_Write(0, &eeprom, sizeof(eeprom));
234  return status;
235 }
Bus handler.
Definition: bus.h:92
status_e bus_release(const struct heivs_bus_t *bus)
Release exclusive access to the bus.
Definition: bus.c:149
status_e EEPROM_FirstInit(uint8_t number, uint8_t *macAddr)
First initialisation of EEPROM.
Definition: eeprom.c:216
EEPROM has no touchscreen calibration data.
Definition: error.h:94
void delay_wait_ms(uint32_t ms)
Wait for at least that time.
Definition: delay.c:12
#define MAGIC_NUMBER
Structure of the eeprom.
Definition: eeprom.c:18
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dest, int n, size_t n)
EEPROM is empty or has failed.
Definition: error.h:93
ARMEBS4 eeprom access functions.
status_e bus_write(const struct heivs_bus_t *bus, uint32_t address, const void *data, size_t len)
Write data to the bus.
Definition: bus.c:243
Parameter unsupported.
Definition: error.h:56
status_e bus_init(const struct heivs_bus_t *bus)
initialize the bus
Definition: bus.c:59
static status_e EEPROM_Write(uint16_t address, const void *src, size_t size)
Write data in EEPROM for a given size.
Definition: eeprom.c:71
const struct heivs_bus_t bus_i2c[BSP_I2C_BUS_COUNT]
All i2c busses.
Definition: stm32_i2c.c:424
status_e EEPROM_Calib_Write(const uint8_t calib[24])
Write the touch calbration to EEPROM.
Definition: eeprom.c:186
simple delays
status_e EEPROM_Calib_Read(uint8_t calib[24])
Returns the touch calbration from EEPROM.
Definition: eeprom.c:142
status_e EEPROM_ReadMacAddress(uint8_t *mac)
Returns the mac address.
Definition: eeprom.c:165
status_e bus_get(const struct heivs_bus_t *bus)
Get exclusive access to the bus.
Definition: bus.c:134
EEPROM content.
Definition: eeprom.c:25
uint32_t magic
Magic number.
Definition: eeprom.c:27
uint32_t version
Version of data.
Definition: eeprom.c:28
status_e
Known errors.
Definition: error.h:21
static status_e EEPROM_Read(uint16_t address, void *dst, size_t size)
Read data from EEPROM for a given size.
Definition: eeprom.c:43
status_e bus_writeread(const struct heivs_bus_t *bus, uint32_t address, const void *src, size_t src_len, void *dst, size_t dst_len, size_t *rlen)
Combined write and read data.
Definition: bus.c:279
No error.
Definition: error.h:28
i2c bus
status_e EEPROM_ReadUniqueNumber(uint8_t *number)
Returns the unique number from the EEPROM.
Definition: eeprom.c:123