Write to EEPROM on BBB?

Hi,

I try to write some data to EEPROM of BBB out of own (bare-metal) software. Reading data works fine and code for writing should be OK too, unfortunately data are sent to EEPROM but not written.

From schematic I found EEPROMs WP-input has to be pulled to Vss so I connected TP4 of BBB with ground (pins 1/2 of P9). Unfortunately this also did not help.

So…anything else that could be missing?

Thanks!

So…anything else that could be missing?

Hi,
seems nothing is missed. In this case I’d proceed with an oscilloscope:

  1. ensure the WP (U7.5) is really Low level.
  2. look at the i2c diagram and ensure there is an acnowledge to (page) write operation
  3. ensure there is long acnowledge delay on the second page write (otherwise the EEPROM is write protected or some other device responds with the i2c ACK!)

You say you use bare metal soft support. Are you sure your i2c diagarm is correct (correct stop condition)? If not, bytes could be read successfully but page write may not begin…

Write Protect pin is LOW-Active. This means that by grounding this pin you do memory protection

Sure? EEPROM documentation says, write-protection is disabled when WP-input is pulled to Vss. On BBB, Vss is ground so pulling WP to ground should do the trick.

Seems this was a stone to my garden.
I just looked at my board having WP grounded with a jumper. I can successfully write/read the 24C256 eeprom.
The jumper is installed. Then, if Low there is no protection.
The pin is named “WP”. Positive logic. If High, then it (protection) is “true”. Protected. If WP=Low=false, the write operation permitted, no protection.

If you posted your results as suggested you’d have better outcome…
(note: on some chips if WP is left floating, there is NO protection, you can write/read!)

OK, so that’s my current code, based on StarterWare example, writeEEPROM() is called e.g. with addr=4 and length=4 plus some reasonable data:

void writeEEPROM(unsigned ``int addr,unsigned ``int length,``const unsigned ``char *data)
{
I2CPinMuxSetup(0);` SetupI2C(); ```I2CAINTCConfigure();
E2promWrite(addr,length,data);` `}` `` `static` `void` `SetupI2C(``void``)` `{` I2C0ModuleClkConfig(); ```I2CMasterDisable(SOC_I2C_0_REGS);
I2CAutoIdleDisable(SOC_I2C_0_REGS);` I2CMasterInitExpClk(SOC_I2C_0_REGS, 48000000, 12000000, 100000); ```I2CMasterSlaveAddrSet(SOC_I2C_0_REGS, I2C_SLAVE_ADDR);
I2CMasterEnable(SOC_I2C_0_REGS);` `}` `` `static` `void` `E2promWrite(unsigned ``int` `addr,unsigned ``int` `length,``const` `unsigned ``char` `*data)` `{` dataToSlave[0]=(unsigned char)(addr >> 8); ```dataToSlave[1]=(unsigned ``char``)(addr & 0xFF);
memcpy``((``void``*)&dataToSlave[2],data,length);` `` tCount=0; ```rCount=0;
SetupI2CTransmission(length);` `}` `` `static` `void` `SetupI2CTransmission(unsigned ``int` `dcount)` `{` I2CSetDataCount(SOC_I2C_0_REGS,0x02+dcount); ```numOfBytes=I2CDataCountGet(SOC_I2C_0_REGS); ``//Why not use dcount?``` ```CleanUpInterrupts();
I2CMasterControl(SOC_I2C_0_REGS,I2C_CFG_MST_TX);` I2CMasterIntEnableEx(SOC_I2C_0_REGS,I2C_INT_TRANSMIT_READY); ```I2CMasterStart(SOC_I2C_0_REGS);
``
while` `(I2CMasterBusBusy(SOC_I2C_0_REGS)==0);` while (tCount!=numOfBytes); ```I2CMasterStop(SOC_I2C_0_REGS);
}

Remaining code/used ISR is original one provided by TI:

static void I2CIsr(void)
{
unsigned int status = 0;

/* Get only Enabled interrupt status */
status = I2CMasterIntStatus(SOC_I2C_0_REGS);

/*
** Clear all enabled interrupt status except receive ready and
** transmit ready interrupt status
*/
I2CMasterIntClearEx(SOC_I2C_0_REGS,
(status & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY)));

if(status & I2C_INT_RECV_READY)
{
/* Receive data from data receive register */
dataFromSlave[rCount++] = I2CMasterDataGet(SOC_I2C_0_REGS);

/* Clear receive ready interrupt status */
I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_RECV_READY);

if(rCount == numOfBytes)
{
/* Disable the receive ready interrupt /
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_RECV_READY);
/
Generate a STOP */
I2CMasterStop(SOC_I2C_0_REGS);

}
}

if (status & I2C_INT_TRANSMIT_READY)
{
/* Put data to data transmit register of i2c */
I2CMasterDataPut(SOC_I2C_0_REGS, dataToSlave[tCount++]);

/* Clear Transmit interrupt status */
I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY);

if(tCount == numOfBytes)
{
/* Disable the transmit ready interrupt */
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY);
}

}

if (status & I2C_INT_STOP_CONDITION)
{
/* Disable transmit data ready and receive data read interupt */
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_RECV_READY |
I2C_INT_STOP_CONDITION);
flag = 0;
}

if(status & I2C_INT_NO_ACK)
{
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_RECV_READY |
I2C_INT_NO_ACK |
I2C_INT_STOP_CONDITION);
/* Generate a STOP */
I2CMasterStop(SOC_I2C_0_REGS);

flag = 0;
}
}

Well, here is a BeagleBoard forum. I wish you meet somebody using Starterware here, but more luck should be if asking on e2e.ti.com forums.
My suggestion was to look at the i2c diagram (using oscilloscope). This surely helped you understand the case. If you cannot, sorry…

Make sure you remove the write protect that is on the EEPROM and that you do not mess with what is there that is needed to make sure the board boots.

Gerald

Is there any other write-protection than the WP-pin of the chip that has t obe pulled to LOW?

No, Make sure you are using 16b data.

Gerald

Yes, there is.
Wrong i2c diagram. Lack of STOP condition, for example.
This will not prevent you from reading but writing will fail.