Skip to content

Commit 48e29f3

Browse files
committed
Added I2C EEPROM ID/OTP Support
1 parent 5fc00db commit 48e29f3

2 files changed

Lines changed: 83 additions & 30 deletions

File tree

Firmware/FFBoard/Inc/constants.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static const uint8_t SW_VERSION_INT[3] = {1,17,0}; // Version as array. 8 bit ea
112112
#define SIGNATURE
113113
#endif
114114

115-
#if defined(FLASH_OTP_BASE) && defined(FLASH_OTP_END)
115+
#if (defined(FLASH_OTP_BASE) && defined(FLASH_OTP_END)) || (defined(I2C_EEPROM_OTP_ADR) && defined(I2C_PORT_EEPROM))
116116
#define OTPMEMORY
117117
#endif
118118

Firmware/FFBoard/Src/flash_helpers.cpp

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -113,25 +113,33 @@ uint8_t i2cBufferEeprom[sizeof(uint16_t)] = {0};
113113
I2CDevice i2cdeveeprom;
114114
extern I2CPort i2cport_int;
115115

116-
bool Flash_Write(uint16_t adr,uint16_t dat){
116+
/**
117+
* Helper function to write 16b data to i2c eeproms with different block sizes
118+
*/
119+
bool I2C_EEPROM_Write16(uint16_t devAdr,uint16_t adr, uint16_t dat){
117120
uint16_t dataLength = sizeof(dat);
118121
memcpy(i2cBufferEeprom,&dat, dataLength);
119-
adr *= sizeof(dat)/I2C_EEPROM_DATA_SIZE;
120-
adr = I2C_EEPROM_OFS+adr;
121-
uint16_t curAdr = adr;
122-
assert(adr < I2C_EEPROM_SIZE);
122+
uint32_t adrAbs = adr;
123+
adrAbs *= sizeof(dat)/I2C_EEPROM_DATA_SIZE;
124+
uint32_t curAdr = adrAbs;
125+
assert(adrAbs < I2C_EEPROM_SIZE);
123126

124127
// Do segmented writes
128+
125129
bool res = false;
126-
while(curAdr < adr+dataLength){
130+
while(curAdr < adrAbs+dataLength){
127131
// i2cport_int.isDeviceReady(i2cdeveeprom, I2C_EEPROM_ADR, 100, I2C_EEPROM_TIMEOUT,false)
128-
while(!i2cport_int.isDeviceReady(&i2cdeveeprom, I2C_EEPROM_ADR, 100, I2C_EEPROM_TIMEOUT,false)){
132+
while(!i2cport_int.isDeviceReady(&i2cdeveeprom, devAdr, 100, I2C_EEPROM_TIMEOUT,false)){
129133
vTaskDelay(1);
130134
}
131-
132-
uint16_t wLen = std::min<uint16_t>(dataLength,I2C_EEPROM_PAGEWRITE_SIZE - (adr % I2C_EEPROM_PAGEWRITE_SIZE));
133-
res = i2cport_int.writeMem(&i2cdeveeprom, I2C_EEPROM_ADR, curAdr, I2C_EEPROM_ADR_SIZE, i2cBufferEeprom, wLen, I2C_EEPROM_TIMEOUT, false);
134-
//res = HAL_I2C_Mem_Write(&I2C_PORT_EEPROM, I2C_EEPROM_ADR, curAdr, I2C_EEPROM_ADR_SIZE, i2cBufferEeprom, wLen,I2C_EEPROM_TIMEOUT) == HAL_OK;
135+
uint16_t i2cAdr = devAdr;
136+
uint16_t writeAdr = curAdr;
137+
if(curAdr > 0xffff){
138+
writeAdr = curAdr & 0xffff;
139+
i2cAdr |= 0x02; // A17 bit
140+
}
141+
uint16_t wLen = std::min<uint16_t>(dataLength,I2C_EEPROM_PAGEWRITE_SIZE - (adrAbs % I2C_EEPROM_PAGEWRITE_SIZE));
142+
res = i2cport_int.writeMem(&i2cdeveeprom, i2cAdr, writeAdr, I2C_EEPROM_ADR_SIZE, i2cBufferEeprom, wLen, I2C_EEPROM_TIMEOUT, false);
135143
curAdr+=wLen;
136144
if(!res){
137145
break;
@@ -140,24 +148,22 @@ bool Flash_Write(uint16_t adr,uint16_t dat){
140148

141149
return res;
142150
}
143-
bool Flash_ReadWriteDefault(uint16_t adr,uint16_t *buf,uint16_t def){
144-
if(!Flash_Read(adr,buf)){
145-
return Flash_Write(adr, def);
146-
}
147-
return true;
148-
}
151+
149152
/**
150-
* Reads a value and if checkempty is true returns false if the read value is the erased value (0xffff) or not found
153+
* Helper function to read 16b data from i2c eeproms with different block sizes
151154
*/
152-
bool Flash_Read(uint16_t adr,uint16_t *buf, bool checkempty){
153-
adr *= sizeof(*buf)/I2C_EEPROM_DATA_SIZE;
154-
assert(adr < I2C_EEPROM_SIZE);
155-
while(!i2cport_int.isDeviceReady(&i2cdeveeprom, I2C_EEPROM_ADR, 100, I2C_EEPROM_TIMEOUT,false)){
155+
bool I2C_EEPROM_Read16(uint16_t devAdr,uint16_t adr,uint16_t *buf, bool checkempty){
156+
uint32_t adrAbs = (adr * sizeof(*buf)/I2C_EEPROM_DATA_SIZE);
157+
assert(adrAbs < I2C_EEPROM_SIZE);
158+
while(!i2cport_int.isDeviceReady(&i2cdeveeprom, devAdr, 100, I2C_EEPROM_TIMEOUT,false)){
156159
vTaskDelay(1);
157160
}
158-
159-
//bool res = HAL_I2C_Mem_Read(&I2C_PORT_EEPROM, I2C_EEPROM_ADR, I2C_EEPROM_OFS+adr, I2C_EEPROM_ADR_SIZE, i2cBufferEeprom, 2, I2C_EEPROM_TIMEOUT) == HAL_OK;
160-
bool res = i2cport_int.readMem(&i2cdeveeprom, I2C_EEPROM_ADR, I2C_EEPROM_OFS+adr, I2C_EEPROM_ADR_SIZE, i2cBufferEeprom, 2, I2C_EEPROM_TIMEOUT, false);
161+
uint16_t i2cAdr = devAdr;
162+
uint16_t datAdr = adrAbs & 0xffff;
163+
if(adrAbs > 0xffff){
164+
i2cAdr |= 0x02; // If curAdr > 0xffff set bit 1 of addr high
165+
}
166+
bool res = i2cport_int.readMem(&i2cdeveeprom, i2cAdr, datAdr, I2C_EEPROM_ADR_SIZE, i2cBufferEeprom, 2, I2C_EEPROM_TIMEOUT, false);
161167

162168
if(checkempty){
163169
bool empty = true;
@@ -174,6 +180,22 @@ bool Flash_Read(uint16_t adr,uint16_t *buf, bool checkempty){
174180
return res;
175181
}
176182

183+
bool Flash_Write(uint16_t adr,uint16_t dat){
184+
return I2C_EEPROM_Write16(I2C_EEPROM_ADR,adr+I2C_EEPROM_OFS,dat);
185+
}
186+
bool Flash_ReadWriteDefault(uint16_t adr,uint16_t *buf,uint16_t def){
187+
if(!Flash_Read(adr,buf)){
188+
return Flash_Write(adr, def);
189+
}
190+
return true;
191+
}
192+
/**
193+
* Reads a value and if checkempty is true returns false if the read value is the erased value (0xffff) or not found
194+
*/
195+
bool Flash_Read(uint16_t adr,uint16_t *buf, bool checkempty){
196+
return I2C_EEPROM_Read16(I2C_EEPROM_ADR,adr+I2C_EEPROM_OFS,buf,checkempty);
197+
}
198+
177199
/**
178200
* Erases the whole EEPROM to its default value
179201
*/
@@ -182,9 +204,12 @@ bool Flash_Format(){
182204
std::array<uint8_t,I2C_EEPROM_PAGEWRITE_SIZE> eraseBuf;
183205
eraseBuf.fill(I2C_EEPROM_ERASED);
184206
for(uint32_t i=I2C_EEPROM_OFS;i<I2C_EEPROM_SIZE;i+=I2C_EEPROM_PAGEWRITE_SIZE){
185-
186-
//bool res = HAL_I2C_Mem_Write(&I2C_PORT_EEPROM, I2C_EEPROM_ADR, I2C_EEPROM_OFS+i, I2C_EEPROM_ADR_SIZE, eraseBuf.data(), std::min<int>(I2C_EEPROM_PAGEWRITE_SIZE,I2C_EEPROM_SIZE-i),I2C_EEPROM_TIMEOUT) == HAL_OK;
187-
bool res = i2cport_int.writeMem(&i2cdeveeprom, I2C_EEPROM_ADR, I2C_EEPROM_OFS+i, I2C_EEPROM_ADR_SIZE, eraseBuf.data(), std::min<int>(I2C_EEPROM_PAGEWRITE_SIZE,I2C_EEPROM_SIZE-i), I2C_EEPROM_TIMEOUT, false);
207+
uint16_t datAdr = i & 0xffff;
208+
uint16_t devAdr = I2C_EEPROM_ADR;
209+
if(i > 0xffff){
210+
devAdr |= 0x02;
211+
}
212+
bool res = i2cport_int.writeMem(&i2cdeveeprom, devAdr, datAdr, I2C_EEPROM_ADR_SIZE, eraseBuf.data(), std::min<int>(I2C_EEPROM_PAGEWRITE_SIZE,I2C_EEPROM_SIZE-i), I2C_EEPROM_TIMEOUT, false);
188213
if(!res){
189214
flag = false;
190215
}else{
@@ -281,6 +306,34 @@ __weak bool OTP_Read(uint16_t adroffset,uint64_t* dat){
281306
*dat = curval;
282307
return true;
283308
}
309+
#elif defined(I2C_EEPROM_OTP_ADR) && defined(I2C_PORT_EEPROM)
310+
// I2C EEPROM OTP/ID memory
311+
__weak bool OTP_Write(uint16_t adroffset,uint64_t dat){
312+
// Write 4 x 16b
313+
for(uint8_t i = 0; i < 4; i++){
314+
bool res = I2C_EEPROM_Write16(I2C_EEPROM_OTP_ADR, 4*adroffset + (i), (dat >> (i*16)) & 0xffff);
315+
if(!res){
316+
return false;
317+
}
318+
}
319+
320+
return true;
321+
}
322+
323+
324+
__weak bool OTP_Read(uint16_t adroffset,uint64_t* dat){
325+
uint64_t val = 0;
326+
for(uint8_t i = 0; i < 4; i++){
327+
uint16_t tdat = 0;
328+
bool res = I2C_EEPROM_Read16(I2C_EEPROM_OTP_ADR, 4*adroffset + (i), &tdat,false);
329+
val |= (uint64_t)tdat << (i*16);
330+
if(!res){
331+
return false;
332+
}
333+
}
334+
*dat = val;
335+
return true;
336+
}
284337
#else
285338
__weak bool OTP_Write(uint16_t adroffset,uint64_t dat){
286339
return false;
@@ -310,4 +363,4 @@ void Flash_Write_Defaults(){
310363
for(const std::pair<uint16_t,uint16_t> &kv : flash_factory_defaults){
311364
Flash_Write(kv.first, kv.second); // Try to write values
312365
}
313-
}
366+
}

0 commit comments

Comments
 (0)