#include #include #include "eeprom.h" /* wait for I2C status register flags to appear */ static bool i2c_wait(uint32_t i2c, uint32_t sr1, uint32_t sr2) { unsigned int i; for (i = 0; i < 1000000; i++) { if (((I2C_SR1(i2c) & sr1) == sr1) && ((I2C_SR2(i2c) & sr2) == sr2)) return true; } return false; } int eeprom_read(uint8_t *buf_out, unsigned int num_bytes, uint16_t read_addr) { unsigned int i; if (num_bytes > 255) return -EINVAL; /* no reload cycles yet */ i2c_send_start(I2C1); /* Wait for the end of the start condition, master mode selected, and BUSY bit set */ if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY)) return -EIO; /* Send Address, wait until it is transferred */ i2c_send_7bit_address(I2C1, 0x50, I2C_WRITE); if (!i2c_wait(I2C1, I2C_SR1_ADDR, 0)) return -EIO; /* Send memory address */ #if 0 /* 16bit address */ i2c_send_data(I2C1, read_addr >> 8); if (!i2c_wait(I2C1, I2C_SR1_BTF, 0)) return -EIO; #endif i2c_send_data(I2C1, read_addr & 0xff); if (!i2c_wait(I2C1, I2C_SR1_BTF, 0)) return -EIO; /* re-start */ i2c_send_start(I2C1); i2c_enable_ack(I2C1); /* Wait for the end of the start condition, master mode selected, and BUSY bit set */ if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY)) return -EIO; /* Send Address, wait until it is transferred */ i2c_send_7bit_address(I2C1, 0x50, I2C_READ); if (!i2c_wait(I2C1, I2C_SR1_ADDR, 0)) return -EIO; for (i = 0; i < num_bytes; i++) { if (i == num_bytes - 1) i2c_disable_ack(I2C1); if (!i2c_wait(I2C1, I2C_SR1_RxNE, 0)) return -EIO; buf_out[i] = i2c_get_data(I2C1); } i2c_send_stop(I2C1); return i; } static int wait_write_complete(void) { unsigned int i; for (i = 0; i < 100; i++) { i2c_send_start(I2C1); /* Wait for the end of the start condition, master mode selected, and BUSY bit set */ if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY)) return -EIO; /* Send Address, wait until it is transferred */ i2c_send_7bit_address(I2C1, 0x50, I2C_WRITE); if (i2c_wait(I2C1, I2C_SR1_ADDR, 0)) { /* slave has sent an ACK, we may proceed */ return 0; } i2c_send_stop(I2C1); } } int eeprom_write_byte(uint16_t write_addr, uint8_t byte) { i2c_send_start(I2C1); /* Wait for the end of the start condition, master mode selected, and BUSY bit set */ if (!i2c_wait(I2C1, I2C_SR1_SB, I2C_SR2_MSL|I2C_SR2_BUSY)) return -EIO; /* Send Address, wait until it is transferred */ i2c_send_7bit_address(I2C1, 0x50, I2C_WRITE); if (!i2c_wait(I2C1, I2C_SR1_ADDR, 0)) return -EIO; /* Send memory address */ #if 0 /* 16bit address */ i2c_send_data(I2C1, write_addr >> 8); if (!i2c_wait(I2C1, I2C_SR1_BTF, 0)) return -EIO; #endif i2c_send_data(I2C1, write_addr & 0xff); if (!i2c_wait(I2C1, I2C_SR1_BTF, 0)) return -EIO; /* Send data to write */ i2c_send_data(I2C1, byte); if (!i2c_wait(I2C1, I2C_SR1_BTF, 0)) return -EIO; i2c_send_stop(I2C1); wait_write_complete(); return 1; }