mirror of
				https://github.com/Rockbox/rockbox.git
				synced 2025-10-29 00:36:22 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			110 lines
		
	
	
		
			No EOL
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			No EOL
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| ---
 | |
| --- I2C
 | |
| ---
 | |
| STMP.i2c = {} 
 | |
| 
 | |
| local h = HELP:get_topic("STMP"):create_topic("i2c")
 | |
| h:add("The STMP.clkctrl table handles the i2c device for all STMPs.")
 | |
| 
 | |
| function STMP.i2c.init()
 | |
|     HW.I2C.CTRL0.SFTRST.set()
 | |
|     STMP.pinctrl.i2c.setup()
 | |
|     STMP.i2c.reset()
 | |
|     STMP.i2c.set_speed(true)
 | |
| end
 | |
| 
 | |
| function STMP.i2c.reset()
 | |
|     HW.I2C.CTRL0.SFTRST.set()
 | |
|     HW.I2C.CTRL0.SFTRST.clr()
 | |
|     HW.I2C.CTRL0.CLKGATE.clr()
 | |
|     -- errata for IMX233
 | |
|     if STMP.is_imx233() then
 | |
|         HW.I2C.CTRL1.ACK_MODE.set();
 | |
|     end
 | |
| end
 | |
| 
 | |
| function STMP.i2c.set_speed(fast)
 | |
|     if fast then
 | |
|         -- Fast-mode @ 400K
 | |
|         HW.I2C.TIMING0.write(0x000F0007)  -- tHIGH=0.6us, read at 0.3us
 | |
|         HW.I2C.TIMING1.write(0x001F000F) -- tLOW=1.3us, write at 0.6us
 | |
|         HW.I2C.TIMING2.write(0x0015000D)
 | |
|     else
 | |
|         -- Slow-mode @ 100K
 | |
|         HW.I2C.TIMING0.write(0x00780030)
 | |
|         HW.I2C.TIMING1.write(0x00800030)
 | |
|         HW.I2C.TIMING2.write(0x00300030)
 | |
|     end
 | |
| end
 | |
| 
 | |
| function STMP.i2c.transmit(slave_addr, buffer, send_stop)
 | |
|     local data = { slave_addr }
 | |
|     for i, v in ipairs(buffer) do
 | |
|         table.insert(data, v)
 | |
|     end
 | |
|     if #data > 4 then
 | |
|         error("PIO mode cannot send more than 4 bytes at once")
 | |
|     end
 | |
|     HW.I2C.CTRL0.MASTER_MODE.set()
 | |
|     HW.I2C.CTRL0.PIO_MODE.set()
 | |
|     HW.I2C.CTRL0.PRE_SEND_START.set()
 | |
|     HW.I2C.CTRL0.POST_SEND_STOP.write(send_stop and 1 or 0)
 | |
|     HW.I2C.CTRL0.DIRECTION.set()
 | |
|     HW.I2C.CTRL0.SEND_NAK_ON_LAST.clr()
 | |
|     HW.I2C.CTRL0.XFER_COUNT.write(#data)
 | |
|     local v = 0
 | |
|     for i,d in ipairs(data) do
 | |
|         v = v + bit32.lshift(d, (i - 1) * 8)
 | |
|     end
 | |
|     HW.I2C.DATA.write(v)
 | |
|     HW.I2C.CTRL1.clr(0xffff)
 | |
|     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 false
 | |
|     end
 | |
|     if HW.I2C.CTRL1.EARLY_TERM_IRQ.read() == 1 or HW.I2C.CTRL1.MASTER_LOSS_IRQ.read() == 1 then
 | |
|         return false
 | |
|     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 |