22 #define I2C_TIMEOUT 100
25 static bool _dbg =
false;
49 static inline bool i2cOut(
I2C_Device * dev, uint8_t data, uint8_t flags)
57 if (!i2cWait(dev))
return false;
70 static inline bool i2cIn(
I2C_Device * dev, uint8_t * data, uint8_t flags)
75 if (!i2cWait(dev))
return false;
87 for (i = 0; i < 2; i++) {
111 int ifno = (((uint32_t)dev_) >> 4) & 0x0F;
133 uint32_t pres = ( WISHBONE_FREQ / ( 5 * bitrate ) ) - 1;
135 dev->
PRE_LO = pres & 0xff;
136 dev->
PRE_HI = ( pres >> 8 ) & 0xff;
168 if (_dbg) printf(
"I2C %02x (Rd)", addr);
170 if (!i2cOut(dev, ( addr << 1 ) | 1,
I2C_CMD_START))
goto exit_f;
172 for (i = 0; i < len; ++i)
174 if (!i2cIn(dev, byte, i == ( len - 1 ) ? I2C_CMD_STOP |
I2C_CMD_ACK : 0))
goto exit_f;
175 if (_dbg) printf(
" %02x", *byte);
183 if (_dbg) puts(
" (err!)");
194 if (_dbg) printf(
"I2C %02x (RdReg=%02x)", addr, reg);
197 if (!i2cOut(dev, ( addr << 1 ) | 0,
I2C_CMD_START))
goto exit_f;
199 if (!i2cOut(dev, reg,
I2C_CMD_ACK | I2C_CMD_STOP))
goto exit_f;
202 if (!i2cOut(dev, ( addr << 1 ) | 1,
I2C_CMD_START))
goto exit_f;
204 for (i = 0; i < len; ++i)
206 if (!i2cIn(dev, byte, i == ( len - 1 ) ? I2C_CMD_STOP |
I2C_CMD_ACK : 0))
goto exit_f;
207 if (_dbg) printf(
" %02x", *byte);
214 if (_dbg) puts(
" (err!)");
224 if (_dbg) printf(
"I2C %02x (Wr)", addr);
227 if (!i2cOut(dev, ( addr << 1 ) | 0,
I2C_CMD_START))
goto exit_f;
229 for (i = 0; i < len; ++i)
231 if (_dbg) printf(
" %02x", *byte);
233 if (!i2cOut(dev, *byte, i == ( len - 1 ) ? I2C_CMD_STOP : 0))
goto exit_f;
241 if (_dbg) puts(
" (err!)");
252 if (_dbg) printf(
"I2C %02x (WrReg=%02x)", addr, reg);
256 if (!i2cOut(dev, ( addr << 1 ) | 0,
I2C_CMD_START))
goto exit_f;
260 if (!i2cOut(dev, reg, 0))
goto exit_f;
262 for (i = 0; i < len; ++i)
264 if (_dbg) printf(
" %02x", *byte);
266 if (!i2cOut(dev, *byte, i == ( len - 1 ) ? I2C_CMD_STOP : 0))
goto exit_f;
275 if (_dbg) puts(
" (err!)");
282 if (!
i2cWrite(dev, addr, wr, wrLen))
return false;
283 return i2cRead(dev, addr, rd, rdLen);
296 if (!i2cOut(dev, ( addr << 1 ) | 0,
I2C_CMD_START))
goto exit_f;
299 for (i = 0; i < cmd_len; ++i)
301 if (!i2cOut(dev, *cmd, 0))
goto exit_f;
306 for (i = 0; i < answer_len; ++i)
308 if (!i2cIn(dev, answer, i == ( answer_len - 1 ) ? I2C_CMD_STOP |
I2C_CMD_ACK : 0))
goto exit_f;
320 static bool i2cCheckedStart(
I2C_Device * dev, uint8_t rawAddr) {
333 if (i2cCheckedStart(dev, (addr << 1) | 1)) {
344 if (i2cCheckedStart(dev, (addr << 1))) {
361 if (_dbg) printf(
"I2C %02x (RdRegAlt=%02x)", addr, reg_addr);
366 if (!i2cOut(dev, ( addr << 1 ) | 1,
I2C_CMD_START))
goto exit_f;
369 if (!i2cOut(dev, reg_addr, 0))
goto exit_f;
372 for (i = 0; i < len; ++i)
376 if (i == ( len - 1 )) f |= I2C_CMD_STOP |
I2C_CMD_ACK;
378 if (!i2cIn(dev, answer, f))
goto exit_f;
380 if (_dbg) printf(
" %02x", *answer);
389 if (_dbg) puts(
" (err!)");
394 void i2cDebug(
bool enable)
bool i2cWrite(I2C_Device *dev, i2cAddr addr, uint8_t *bytes, int len)
Writes to the I2C device.
volatile unsigned int PRE_HI
Prescaler high.
bool i2cExists(I2C_Device *dev, i2cAddr addr, bool *canRead, bool *canWrite)
Checks whether or not an I2C address is present on the bus.
#define I2C_IF_NO_MASK
Interface number mask.
#define E_I2C_NO_ACK
I2C device did not acknowledge TX.
volatile unsigned int PRE_LO
Prescaler low.
volatile unsigned int CTL
Control.
volatile unsigned int IF
Interface no. register (WR extension)
Structure defines OpenCores I2C Device.
#define I2C_STS_ARBLOST
Arbitration lost.
#define E_I2C_TIME_OUT
I2C device timed out.
#define I2C_STS_RXACK
Not Acknowledge receive.
void timeDelay(uint32_t msec)
Simple busy-wait delay.
bool i2cSendCmdAlt(I2C_Device *dev, i2cAddr addr, uint8_t *cmd, int cmd_len, uint8_t *answer, int answer_len)
Writes a command to the I2C device and receive the answer.
#define E_I2C_ARB_LOST
Arbitration on the I2C bus lost.
uint8_t i2cAddr
I2C address type.
#define I2C_CMD_IACK
I2C ACK interrupt.
bool i2cReadReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *rd, int rdLen)
Reads from the I2C device register.
#define I2C_CMD_WR
Write command.
#define I2C_CMD_ACK
Though bit is named ACK, its really NACK when set to 1.
bool i2cWriteRead(I2C_Device *dev, i2cAddr addr, uint8_t *wr, int wrLen, uint8_t *rd, int rdLen)
Writes and Reads To and from the I2C device.
bool i2cWriteReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *wr, int wrLen)
Writes to the I2C device register.
static uint32_t timeOutInit(uint32_t msec)
Initializes a timeout with the specified no of msecs.
#define I2C_CTL_CORE_ENA
Enable core.
#define I2C_CMD_STOP
Issue stop.
#define E_I2C_INIT
I2C WB device failed to initialize properly.
static bool timeOut(uint32_t to)
Checks whether or not the timeout has expired.
Manages the global system error.
bool i2cInit(I2C_Device *dev, uint32_t bitrate)
Initializes the I2C device with the specified bitrate.
volatile unsigned int TXRX
Transmit / Receive.
bool i2cReadRegAlt(I2C_Device *dev, i2cAddr addr, uint8_t reg_addr, uint8_t *answer, int len)
Reads a register from a I2C device.
#define I2C_CMD_START
Issue start.
void errClear()
Clears the current error.
#define I2C_IF_NO_SHIFT
Interface no shift.
#define I2C_CMD_RD
Read command.
uint32_t errGet()
Returns the last error code, or null.
bool i2cRead(I2C_Device *dev, i2cAddr addr, uint8_t *bytes, int len)
Reads from the I2C device.
volatile unsigned int CMDSTS
Command and Status.
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
#define ERROR(CODE,...)
Expands an error code to an error code with a description (if ERROR_W_DESCR is declared).
#define I2C_STS_TIP
Transfer in progress.
OpenCores I2C device driver.