#define I2C_CFG_MSTEN (0x1)
#define I2C_CFG_SLVEN (0x2)
#define I2C_STAT_MSTPENDING (0x1)
#define I2C_STAT_MSTSTATE (0xe)
#define I2C_STAT_MSTST_IDLE (0x0)
#define I2C_STAT_MSTST_RX (0x2)
#define I2C_STAT_MSTST_TX (0x4)
#define I2C_STAT_MSTST_NACK_ADDR (0x6)
#define I2C_STAT_MSTST_NACK_TX (0x8)
#define I2C_STAT_SLVPENDING (0x100)
#define I2C_STAT_SLVSTATE (0x600)
#define I2C_STAT_SLVST_ADDR (0x000)
#define I2C_STAT_SLVST_RX (0x200)
#define I2C_STAT_SLVST_TX (0x400)
#define I2C_MSTCTL_MSTCONTINUE (0x1)
#define I2C_MSTCTL_MSTSTART (0x2)
#define I2C_MSTCTL_MSTSTOP (0x4)
#define I2C_SLVCTL_SLVCONTINUE (0x1)
#define I2C_SLVCTL_SLVNACK (0x2)
@ ------------------------------------------------------------------------------------
waiti2c: LDR R0,[R3,IICSTAT]
LSRS R1,R0,#1
BCC.n waiti2c
BX LR
@ ------------------------------------------------------------------------------------
writei2c: PUSH {R2-R5,LR} @ address in R1
MOVS R4,R0 @ data in R0
MOVS R5,R1
LDR R3,=LPC_I2C_BASE
MOVS R0,I2C_CFG_MSTEN
STR R0,[R3,IICCFG]
BL waiti2c @ wait for idle
ANDS R0,R0,#I2C_STAT_MSTSTATE
BNE.n i2cabort
LSLS R0,R5,#1 @ address with RW=0
STR R0,[R3,IICMSTDAT]
MOVS R0,#I2C_MSTCTL_MSTSTART @ send start
STR R0,[R3,IICMSTCTL]
BL waiti2c @ wait for idle
ANDS R0,R0,#I2C_STAT_MSTSTATE
CMP R0,#I2C_STAT_MSTST_TX
BNE.N i2cabort
ANDS R0,R0,#I2C_STAT_MSTSTATE
STR R4,[R3,IICMSTDAT] @ send data
MOVS R0,#I2C_MSTCTL_MSTCONTINUE @ continue
STR R0,[R3,IICMSTCTL]
BL waiti2c @ wait for completion
ANDS R0,R0,#I2C_STAT_MSTSTATE
CMP R0,#I2C_STAT_MSTST_TX
BNE.N i2cabort
MOVS R0,#I2C_MSTCTL_MSTSTOP @ send STOP
STR R0,[R3,IICMSTCTL]
BL waiti2c @ wait for completion
ANDS R0,R0,#I2C_STAT_MSTSTATE
BNE.n i2cabort
POP {R2-R5,PC}
i2cabort: MVNS R0,#0
POP {R2-R5,PC}
@ ------------------------------------------------------------------------------------
readi2c: PUSH {R2-R5,LR} @ address in R1
MOVS R4,R1 @ returns 16 bits of data in R0
LDR R3,=LPC_I2C_BASE
MOVS R0,I2C_CFG_MSTEN
STR R0,[R3,IICCFG]
BL waiti2c
ANDS R0,R0,#I2C_STAT_MSTSTATE
BNE.n i2cabort
LSLS R0,R4,#1
ADDS R0,R0,#1 @ RW set for read
STR R0,[R3,IICMSTDAT]
MOVS R0,#I2C_MSTCTL_MSTSTART
STR R0,[R3,IICMSTCTL] @ send START
BL waiti2c @ wait for completion
ANDS R0,R0,#I2C_STAT_MSTSTATE
CMP R0,#I2C_STAT_MSTST_RX
BNE.N i2cabort
LDR R4,[R3,IICMSTDAT] @ read data
MOVS R0,#I2C_MSTCTL_MSTCONTINUE @ continue
STR R0,[R3,IICMSTCTL]
BL waiti2c @ wait for completion
ANDS R0,R0,#I2C_STAT_MSTSTATE
CMP R0,#I2C_STAT_MSTST_RX
BNE.N i2cabort
LDR R0,[R3,IICMSTDAT] @ load data
ADDS R4,R0,R4,LSL #8
MOVS R0,#I2C_MSTCTL_MSTSTOP @ send STOP
STR R0,[R3,IICMSTCTL]
BL waiti2c @ wait for completion
ANDS R0,R0,#I2C_STAT_MSTSTATE
BNE.n i2cabort
MOVS R0,R4
POP {R2-R5,PC}
@ ------------------------------------------------------------------------------------ |