/************************* * ls7a *************************/ #define MISC_BASE 0x90000e0010080000 #define LS7A_I2C0_REG_BASE (MISC_BASE + 0x10000) #define LS7A_I2C0_PRER_LO_REG (LS7A_I2C0_REG_BASE + 0x0) #define LS7A_I2C0_PRER_HI_REG (LS7A_I2C0_REG_BASE + 0x1) #define LS7A_I2C0_CTR_REG (LS7A_I2C0_REG_BASE + 0x2) #define LS7A_I2C0_TXR_REG (LS7A_I2C0_REG_BASE + 0x3) #define LS7A_I2C0_RXR_REG (LS7A_I2C0_REG_BASE + 0x3) #define LS7A_I2C0_CR_REG (LS7A_I2C0_REG_BASE + 0x4) #define LS7A_I2C0_SR_REG (LS7A_I2C0_REG_BASE + 0x4) #define CR_START 0x80 #define CR_STOP 0x40 #define CR_READ 0x20 #define CR_WRITE 0x10 #define CR_ACK 0x8 #define CR_IACK 0x1 #define SR_NOACK 0x80 #define SR_BUSY 0x40 #define SR_AL 0x20 #define SR_TIP 0x2 #define SR_IF 0x1 #define i2c_wait_tip \ dli v0, LS7A_I2C0_SR_REG; \ 1: \ lb v1, 0x0(v0); \ andi v1, v1, SR_TIP; \ bnez v1, 1b; \ nop #define i2c_wait_ack \ dli v0, LS7A_I2C0_SR_REG; \ 1: \ lb v1, 0x0(v0); \ and v1, v1, SR_NOACK; \ bnez v1, 1b; \ nop LEAF(i2cinit) #if 0 //i2c0 sel dli v1, 0x90000e005ff00440 lb v0, 0x0(v1) or v0, (1 << 4) sb v0, 0x0(v1) #endif //LPB clock_a,SCL clock_s,prescale = clock_a / (4 * clock_s); li v1, 0 dli v0, LS7A_I2C0_CTR_REG sb v1, 0x0(v0) li v1, 0x71 dli v0, LS7A_I2C0_PRER_LO_REG sb v1, 0x0(v0) li v1, 0x2 dli v0, LS7A_I2C0_PRER_HI_REG sb v1, 0x0(v0) li v1, 0x80 dli v0, LS7A_I2C0_CTR_REG sb v1, 0x0(v0) jr ra nop END(i2cinit) LEAF(i2cread) /* * use register: * v0, v1 * a0, a1 * input: a0,a1 * a0: device ID * a1: register offset * v0: return value * */ /*i2c_send_b*/ /* load device address */ andi v1, a0, 0xfe dli v0, LS7A_I2C0_TXR_REG sb v1, 0x0(v0) /* send start frame */ li v1, CR_START | CR_WRITE dli v0, LS7A_I2C0_CR_REG sb v1, 0x0(v0) /* waite send finished */ // i2c_wait_tip dli v0, LS7A_I2C0_SR_REG 1: lb v1, 0x0(v0) andi v1, v1, SR_TIP bnez v1, 1b nop /* load data to be send */ move v1, a1 dli v0, LS7A_I2C0_TXR_REG sb v1, 0x0(v0) /* send data frame */ li v1, CR_WRITE dli v0, LS7A_I2C0_CR_REG sb v1, 0x0(v0) /* waite send finished */ // i2c_wait_tip dli v0, LS7A_I2C0_SR_REG 1: lb v1, 0x0(v0) andi v1, v1, SR_TIP bnez v1, 1b nop /* i2c_read_b */ /* load device address */ ori v1, a0, 0x1 dli v0, LS7A_I2C0_TXR_REG sb v1, 0x0(v0) /* send start frame */ li v1, CR_START | CR_WRITE dli v0, LS7A_I2C0_CR_REG sb v1, 0x0(v0) /* waite send finished */ // i2c_wait_tip dli v0, LS7A_I2C0_SR_REG 1: lb v1, 0x0(v0) andi v1, v1, SR_TIP bnez v1, 1b nop /* receive data to fifo */ li v1, CR_READ | CR_ACK dli v0, LS7A_I2C0_CR_REG sb v1, 0x0(v0) // i2c_wait_tip dli v0, LS7A_I2C0_SR_REG 1: lb v1, 0x0(v0) andi v1, v1, SR_TIP bnez v1, 1b nop /* read data from fifo */ dli v0, LS7A_I2C0_RXR_REG lb a1, 0x0(v0) /* i2c_stop */ /* free i2c bus */ dli v0, LS7A_I2C0_CR_REG li v1, CR_STOP sb v1, 0x0(v0) 1: dli v0, LS7A_I2C0_SR_REG lb v1, 0x0(v0) andi v1, v1, SR_BUSY bnez v1, 1b nop move v0, a1 jr ra nop END(i2cread)