Код (сокращенный, полностью в архиве):
eeprom.c
- Код: Выделить всё
uint8_t eeprom_read(uint16_t address, void* buf, uint16_t count)
{
uint8_t *b = buf;
I2C_START;
uint8_t ack = i2c_write(EEPROM_ADDRESS);
if (ack) {
I2C_STOP;
return ack;
}
ack = i2c_write(address >> 8);
if (ack) {
I2C_STOP;
return ack;
}
ack = i2c_write(address & 0xFF);
if (ack) {
I2C_STOP;
return ack;
}
I2C_STOP;
I2C_START;
ack = i2c_write(EEPROM_ADDRESS | 1);
if (ack) {
I2C_STOP;
return ack;
}
while (count) {
*b = i2c_read(count > 1);
b++;
count--;
}
I2C_STOP;
return ack;
}
uint8_t eeprom_write(uint16_t address, void* buf, uint16_t count)
{
uint8_t *b = buf;
uint8_t ack = 0;
while (count) {
PORTC ^= 2;
uint8_t nbytes = 64 - (address & 63);
if (nbytes > count) nbytes = count;
uint8_t attempts = 100;
while (attempts--) {
I2C_START;
ack = i2c_write(EEPROM_ADDRESS);
if (!ack) break;
else I2C_STOP;
}
if (ack) {
return ack;
}
ack = i2c_write(address >> 8);
if (ack) {
I2C_STOP;
return ack;
}
ack = i2c_write(address & 0xFF);
if (ack) {
I2C_STOP;
return ack;
}
count -= nbytes;
while (nbytes) {
ack = i2c_write(*b);
if (ack) {
I2C_STOP;
return ack;
}
b++;
nbytes--;
}
I2C_STOP;
address += nbytes;
}
uint8_t attempts = 100;
while (attempts--) {
I2C_START;
uint8_t ack = i2c_write(EEPROM_ADDRESS);
I2C_STOP;
if (!ack) break;
}
return ack;
}
test.c:
- Код: Выделить всё
uint8_t buf[8] = {
1, 2, 3, 4, 5, 6, 7,
};
FILE serial = FDEV_SETUP_STREAM(fputchar, NULL, _FDEV_SETUP_WRITE);
int main(void)
{
stdout = &serial;
UBRRH = 0;
UBRRL = 197;
DDRD = (1 << 1); // TXD
DDRC = 2; // debug
UCSRB = (1 << TXEN);
if (eeprom_write(0, buf, 8)) printf("WRITE FAIL!\n\n");
if (!eeprom_read(0, buf, 8)) {
printf("%02X ", buf[0]);
printf("%02X ", buf[1]);
printf("%02X ", buf[2]);
printf("%02X ", buf[3]);
printf("%02X ", buf[4]);
printf("%02X ", buf[5]);
printf("%02X ", buf[6]);
printf("%02X\n", buf[7]);
}
for(;;);
}
Чтение проходит нормально. ПЗУ поставил с записанными данными, в терминале их вижу. А новые не записываются. Когда пытаюсь писать не 8 байт, а больше, по импульсам на ноге PORTC.1 вижу, что цикл записи страницы занимает ровно столько времени, сколько нужно для вывода 67 байт (адрес I2c, 2 байта адреса памяти, 64 байта данных). По идее оно должно быть больше, так как ПЗУ после стоп-бита нужно до 5 мс для записи данных.
Подтяжку на шине I2C проверил. Нога WP притянута к земле. Что я делаю не так?