/***************************************************************************** */
-/* EEPROM Chip select for the GPIO Demo module */
-/*******************************************************************************/
-/* Set the SPI SSEL pin low. */
-/* These functions are specific to the mod_gpio_demo and domotab modules.
- * It is used to release the gate that blocks the SCL signal to the EEPROM,
- * allowing multiple eeproms with the same address to be accessed one at a time
- * on the same I2C Bus, which gives a way to both identify modules presence and
- * module function, name, and pther capabilities.
- * When the SPI is used as slave, the master has the control of the SPI SSEL signal
- * and the EEPROM should not be accessed by the module.
- * Other I2C EEPROMs should not need these functions.
- */
-static const struct pio i2c_eeprom_cs = LPC_GPIO_0_15;
-int mod_gpio_demo_eeprom_cs_pull_low(void)
-{
- /* Configure SPI_CS as output and set it low. */
- config_gpio(&i2c_eeprom_cs, 0, GPIO_DIR_OUT, 0);
- return 0;
-}
-void mod_gpio_demo_eeprom_cs_release(void)
-{
- struct lpc_gpio* gpio_port_regs = LPC_GPIO_REGS(i2c_eeprom_cs.port);
- gpio_port_regs->set = (1 << i2c_eeprom_cs.pin);
-}
+/* Read and Write for eeprom */
+/***************************************************************************** */
+/* NOTE : This code does automatic detection of the eeprom type/size and thus does not
+ * support multiple eeproms on the same I2C bus
+ */
-/***************************************************************************** */
-/* Read and Write for module eeprom */
-/***************************************************************************** */
/* Config */
/* Small eeprom : up to 2k bytes. These use a segment address on the lower three bits
* of the address byte, and thus reply on 8 consecutive addresses */
-#define EEPROM_ID_SMALL_ADDR 0xA0
+#define EEPROM_ID_SMALL_ADDR_1 0xA0
+#define EEPROM_ID_SMALL_ADDR_2 0xA2
#define EEPROM_ID_SMALL_I2C_SIZE 1024
#define EEPROM_ID_SMALL_PAGE_SIZE 16
/* Big eeprom : from 4k bytes and above : These use two address bytes, and the three
- * physical address pins are used to set the chip address. On DTPlug modules they should
- * have address 0xA8. */
-#define EEPROM_ID_BIG_ADDR 0xA8
+ * physical address pins are used to set the chip address. */
#define EEPROM_ID_BIG_I2C_SIZE 16*1024
#define EEPROM_ID_BIG_PAGE_SIZE 64
+enum i2c_eeprom_type {
+ EEPROM_TYPE_NONE = 0,
+ EEPROM_TYPE_SMALL,
+ EEPROM_TYPE_BIG,
+};
/* Detect the eeprom size */
-int eeprom_detect(void)
+int eeprom_detect(uint8_t eeprom_addr)
{
int ret = 0;
- char cmd_buf[1] = { EEPROM_ID_SMALL_ADDR, };
+ char cmd_buf[1] = { EEPROM_ID_SMALL_ADDR_1, };
- /* Look for small eeproms first, only these would answer on EEPROM_ID_SMALL_ADDR */
+ /* Look for small eeproms first, only these would answer on all addresses */
+ if (eeprom_addr == EEPROM_ID_SMALL_ADDR_1) {
+ cmd_buf[0] = EEPROM_ID_SMALL_ADDR_2;
+ }
ret = i2c_read(cmd_buf, 1, NULL, NULL, 0);
if (ret == 0) {
return EEPROM_TYPE_SMALL;
}
+
/* No small eeprom ... look for big ones */
- cmd_buf[0] = EEPROM_ID_BIG_ADDR;
+ cmd_buf[0] = eeprom_addr;
ret = i2c_read(cmd_buf, 1, NULL, NULL, 0);
if (ret == 0) {
return EEPROM_TYPE_BIG;
return ret; /* Error or module size */
}
-int get_eeprom_type(void)
+int get_eeprom_type(uint8_t eeprom_addr)
{
static int eeprom_type = -1;
return eeprom_type; /* No need to check again */
}
- eeprom_type = eeprom_detect();
+ eeprom_type = eeprom_detect(eeprom_addr);
if (eeprom_type <= 0) {
return -1;
}
* -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine
*/
#define CMD_BUF_SIZE 4
-int eeprom_read(uint32_t offset, void *buf, size_t count)
+int eeprom_read(uint8_t eeprom_addr, uint32_t offset, void *buf, size_t count)
{
int ret = 0;
- char cmd_buf[CMD_BUF_SIZE] = { EEPROM_ID_BIG_ADDR, 0, 0, (EEPROM_ID_BIG_ADDR | 0x01), };
+ char cmd_buf[CMD_BUF_SIZE];
char ctrl_buf[CMD_BUF_SIZE] = { I2C_CONT, I2C_CONT, I2C_DO_REPEATED_START, I2C_CONT, };
int eeprom_type = 0;
- if (mod_gpio_demo_eeprom_cs_pull_low() != 0) {
- return -EBUSY;
- }
- eeprom_type = get_eeprom_type();
+ eeprom_type = get_eeprom_type(eeprom_addr);
/* Read the requested data */
switch (eeprom_type) {
case EEPROM_TYPE_SMALL:
- cmd_buf[0] = EEPROM_ID_SMALL_ADDR | ((offset & 0x700) >> 7);
+ cmd_buf[0] = EEPROM_ID_SMALL_ADDR_1 | ((offset & 0x700) >> 7);
cmd_buf[1] = offset & 0xFF;
- cmd_buf[2] = EEPROM_ID_SMALL_ADDR | 0x01;
+ cmd_buf[2] = EEPROM_ID_SMALL_ADDR_1 | 0x01;
ret = i2c_read(cmd_buf, CMD_BUF_SIZE - 1, ctrl_buf + 1, buf, count);
break;
case EEPROM_TYPE_BIG:
+ cmd_buf[0] = eeprom_addr;
cmd_buf[1] = ((offset & 0xFF00) >> 8);
cmd_buf[2] = offset & 0xFF;
+ cmd_buf[3] = (eeprom_addr | 0x01);
ret = i2c_read(cmd_buf, CMD_BUF_SIZE, ctrl_buf, buf, count);
break;
default:
ret = -1;
break;
}
- mod_gpio_demo_eeprom_cs_release();
return ret;
}
#define CMD_SIZE_BIG 3
#define MAX_CMD_SIZE CMD_SIZE_BIG
#define EEPROM_ID_MAX_PAGE_SIZE EEPROM_ID_BIG_PAGE_SIZE
-int eeprom_write(uint32_t offset, const void *buf, size_t count)
+int eeprom_write(uint8_t eeprom_addr, uint32_t offset, const void *buf, size_t count)
{
int ret = 0;
uint8_t cmd_size = CMD_SIZE_BIG, page_size = EEPROM_ID_BIG_PAGE_SIZE;
int write_count = 0, size = 0;
- char cmd[MAX_CMD_SIZE] = { EEPROM_ID_BIG_ADDR, 0, 0 };
+ char cmd[MAX_CMD_SIZE];
char full_buff[(EEPROM_ID_MAX_PAGE_SIZE + MAX_CMD_SIZE)];
int eeprom_type = 0;
- if (mod_gpio_demo_eeprom_cs_pull_low() != 0) {
- return -EBUSY;
- }
- eeprom_type = get_eeprom_type();
+ eeprom_type = get_eeprom_type(eeprom_addr);
switch (eeprom_type) {
case EEPROM_TYPE_SMALL:
while (write_count < count) {
switch (eeprom_type) {
case EEPROM_TYPE_SMALL:
- cmd[0] = EEPROM_ID_SMALL_ADDR | ((offset & 0x700) >> 7);
+ cmd[0] = EEPROM_ID_SMALL_ADDR_1 | ((offset & 0x700) >> 7);
cmd[1] = offset & 0xFF;
break;
case EEPROM_TYPE_BIG:
+ cmd[0] = eeprom_addr;
cmd[1] = ((offset & 0xFF00) >> 8);
cmd[2] = offset & 0xFF;
break;
write_count += size;
}
- mod_gpio_demo_eeprom_cs_release();
if (write_count != count)
return ret;
#include <stdint.h>
-/***************************************************************************** */
-/* Module identification support for DTPlug and DomoTab */
-/***************************************************************************** */
-
-/* Module capabilities */
-#define UEXT_MOD_HAS_NONE 0
-#define UEXT_MOD_HAS_UART (1 << 0)
-#define UEXT_MOD_HAS_I2C (1 << 1)
-#define UEXT_MOD_HAS_SPI (1 << 2)
-
-struct module_desc {
- uint16_t serial_number;
- uint8_t version;
- uint8_t header_size;
- uint8_t capabilities; /* Bit mask of UEXT_MOD_HAS_* */
- uint8_t name_offset;
- uint8_t name_size;
- uint8_t image_offset;
- uint16_t image_size;
-} __attribute__ ((packed));
-
-enum i2c_eeprom_type {
- EEPROM_TYPE_NONE = 0,
- EEPROM_TYPE_SMALL,
- EEPROM_TYPE_BIG,
-};
-
-
-
/***************************************************************************** */
/* Read and Write for system eeprom */
/***************************************************************************** */
/* EEPROM Read
* Performs a non-blocking read on the eeprom.
- * address : data offset in eeprom.
+ * eeprom_addr : address of the I2C eeprom chip (hardware dependent)
+ * offset : data offset in eeprom.
* RETURN VALUE
* Upon successfull completion, returns the number of bytes read. On error, returns a negative
* integer equivalent to errors from glibc.
* -EREMOTEIO : Device did not acknowledge
* -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine
*/
-int eeprom_read(uint32_t offset, void *buf, size_t count);
+int eeprom_read(uint8_t eeprom_addr, uint32_t offset, void *buf, size_t count);
/* EEPROM Write
* Performs a non-blocking write on the eeprom.
- * address : data offset in eeprom.
+ * eeprom_addr : address of the I2C eeprom chip (hardware dependent)
+ * offset : data offset in eeprom.
* RETURN VALUE
* Upon successfull completion, returns the number of bytes written. On error, returns a negative
* integer equivalent to errors from glibc.
* -EREMOTEIO : Device did not acknowledge
* -EIO : Bad one: Illegal start or stop, or illegal state in i2c state machine
*/
-int eeprom_write(uint32_t offset, const void *buf, size_t count);
+int eeprom_write(uint8_t eeprom_addr, uint32_t offset, const void *buf, size_t count);