hwstub: implement i2c and i2c eeprom dump

Change-Id: Iff1b4f40affb88c104e7322e25cdbe34f8886476
diff --git a/utils/hwstub/tools/lua/i2c_scan.lua b/utils/hwstub/tools/lua/i2c_scan.lua
index def7b5d..55066b0 100644
--- a/utils/hwstub/tools/lua/i2c_scan.lua
+++ b/utils/hwstub/tools/lua/i2c_scan.lua
@@ -8,4 +8,41 @@
             print(string.format("%#x OK", i))
         end
     end 
-    end
\ No newline at end of file
+end
+
+-- if file is nil, return array
+-- if size is nil, dump the whole EEPROM
+function I2CSCAN.dump_rom(file, size)
+    STMP.i2c.init()
+    STMP.i2c.set_speed(true)
+    if not STMP.i2c.transmit(0xa0, {0, 0}, false) then
+        error("Cannot send address")
+    end
+    local res = {}
+    if size == nil then
+        size = 0xffff
+    end
+    for i = 0, size do
+        local l = STMP.i2c.receive(0xa0, 1)
+        if l == nil then
+            error("error during transfer")
+        end
+        for i = 1, #l do
+            table.insert(res, l[i])
+        end
+    end
+    if file == nil then
+        return res
+    end
+    local f = file
+    if type(file) == "string" then
+        f = io.open(file, "w")
+    end
+    if f == nil then error("Cannot open file or write to nil") end
+    for i = 1, #res do
+        f:write(string.char(res[i]))
+    end
+    if type(file) == "string" then
+        io.close(f)
+    end
+end
\ No newline at end of file
diff --git a/utils/hwstub/tools/lua/stmp/i2c.lua b/utils/hwstub/tools/lua/stmp/i2c.lua
index 209f1df..dee5aae 100644
--- a/utils/hwstub/tools/lua/stmp/i2c.lua
+++ b/utils/hwstub/tools/lua/stmp/i2c.lua
@@ -73,4 +73,38 @@
     else
         return true
     end
+end
+
+function STMP.i2c.receive(slave_addr, length)
+    if length > 4 then
+        error("PIO mode cannot receive mode than 4 bytes at once")
+    end
+    -- send address
+    HW.I2C.CTRL0.RETAIN_CLOCK.set()
+    STMP.i2c.transmit(bit32.bor(slave_addr, 1), {}, false, true)
+    HW.I2C.CTRL0.DIRECTION.clr()
+    HW.I2C.CTRL0.XFER_COUNT.write(length)
+    HW.I2C.CTRL0.SEND_NAK_ON_LAST.set()
+    HW.I2C.CTRL0.POST_SEND_STOP.set()
+    HW.I2C.CTRL0.RETAIN_CLOCK.clr()
+    HW.I2C.CTRL0.RUN.set()
+    while HW.I2C.CTRL0.RUN.read() == 1 do
+    end
+    if HW.I2C.CTRL1.NO_SLAVE_ACK_IRQ.read() == 1 then
+        if STMP.is_imx233() then
+            HW.I2C.CTRL1.CLR_GOT_A_NAK.set()
+        end
+        STMP.i2c.reset()
+        return nil
+    end
+    if HW.I2C.CTRL1.EARLY_TERM_IRQ.read() == 1 or HW.I2C.CTRL1.MASTER_LOSS_IRQ.read() == 1 then
+        return nil
+    else
+        local data = HW.I2C.DATA.read()
+        local res = {}
+        for i = 0, length - 1 do
+            table.insert(res, bit32.band(0xff, bit32.rshift(data, 8 * i)))
+        end
+        return res
+    end
 end
\ No newline at end of file