NetBurner 3.5.6
PDF Version
i2c.h
1/*NB_REVISION*/
2
3/*NB_COPYRIGHT*/
4
24#ifndef __I2C_H
25#define __I2C_H
26
27#include <predef.h>
28#include <ctype.h>
29#include <sim.h>
30#include <nbrtos.h>
31
32
33#define TWIHS_SR_IOS (TWIHS_SR_SCL | TWIHS_SR_SDA)
34
35struct I2CTxn_t {
36 uint8_t *buf;
37 uint32_t blen;
38 uint8_t regAddr[3];
39 uint8_t devAddr : 7;
40 bool RnW : 1;
41 uint8_t regAddrLen : 3;
42 bool bIssueStop : 1;
43
44 void dump(uint32_t line);
45};
46
47class I2C;
48
49class TwoWire;
50
51/*-------------------------------------------------------------------------------------------------
52 * Wire Interface Class
53 *------------------------------------------------------------------------------------------------*/
54
66class WireIntf {
67 I2C &i2c; // I2C instance of this wire interface
68 uint8_t txnBuf[128]; // Transaction buffer. Build up transaction before being flushed to the I2C bus
69 uint8_t txnLen; // Current transaction length
70 uint8_t devAddr; // I2C slave device adddress to be accessed
71 uint8_t bytesRead; // Number of bytes read, returned by requestFrom(). Provides number of bytes available to read()
72 uint8_t readIdx; // Read index. Location in the transaction buffer of next byte to be read
73 bool bTxnStarted; // Whether or not the wire interface is in an active transaction
74 bool bBusStarted; // Whether or not the bus is active (h/w signal state)
75
76public:
77 WireIntf(I2C &module);
78
84 void begin();
85
99 uint32_t requestFrom(uint8_t addr, uint32_t len, bool stop = true);
100
108 void beginTransmission(uint8_t addr);
109
120 void endTransmission(bool stop = true);
121
132 uint32_t write(uint8_t dat);
133
144 uint32_t write(char * str);
145
156 uint32_t write(uint8_t * buf, uint32_t len);
157
165 uint32_t available();
166
173 uint8_t read();
174
186 void flush(bool bIssueStop = false);
187};
188
189
190/*
191 * I2C WireIntf objects instantiated by the system.
192 *
193 * Provides access to the all the I2C peripherals on the processor. The I2C peripherals available will vary by platform.
194 * For example, Wire.read(); will execute a read operation on I2C module 0.
195 */
196
197
198/*-------------------------------------------------------------------------------------------------
199 * I2C Class
200 *------------------------------------------------------------------------------------------------*/
201
213class I2C {
214public:
228private:
229 enum TxnStat {
230 TXN_RDY,
231 TXN_IN_PROGRESS,
232 TXN_WAITING
233 };
234
235 Twihs &twi;
236 int modNum;
237 TxnStat txnStatus;
238 Result_t txnResult;
239 uint32_t sticky_sr;
240 uint8_t iadrAddressSize; // Number of address register bytes, 0 - 3
241
242 volatile I2CTxn_t *pTxn;
243 OS_SEM txnSem;
244
245 void isr();
246 void isr_rx(uint32_t sr);
247 void isr_tx(uint32_t sr);
248
249 inline uint32_t getStatus()
250 { uint32_t sr = twi.TWIHS_SR; sticky_sr |= sr; return sr; }
251 inline uint32_t getStickyStatus()
252 { uint32_t sr = twi.TWIHS_SR; sticky_sr |= sr; return sticky_sr; }
253 inline void clrStickyStatus() { sticky_sr = 0; }
254
255 inline bool busBusy()
256 { return ((getStatus() & TWIHS_SR_IOS) != TWIHS_SR_IOS); }
257
258 void start(uint8_t deviceAddr, bool rnw, uint8_t regAddrlen = 0, bool bIssueStop = false);
259 void restart(uint8_t deviceAddr, bool rnw, uint8_t regAddrlen = 0, bool bIssueStop = false);
260 void stop();
261
262 Result_t write8(uint8_t dat);
263 Result_t read8(uint8_t &dat);
264 Result_t read8Restart(uint8_t &dat, uint8_t addr, bool Rnw);
265
266public:
273 I2C(int module);
274
275 // Copy constructor
276 I2C(const I2C & rhs)
277 : twi(rhs.twi), modNum(rhs.modNum), txnStatus(rhs.txnStatus)
278 {}
279
286 void setup(uint32_t busSpeed);
287
292 void resetBus();
293
305 Result_t DoTransaction(I2CTxn_t *pTransaction, bool bRepeatedStart = false);
306
321 inline void setNumAddressBytes(uint8_t numAddressBytes = 1) { iadrAddressSize = numAddressBytes; }
322
332 Result_t writeReg8(uint8_t devAddr, uint32_t reg, uint8_t data);
333
343 Result_t readReg8(uint8_t devAddr, uint32_t reg, uint8_t &data);
344
359 Result_t writeRegN(uint8_t devAddr, uint32_t reg, const uint8_t *buf, uint32_t blen);
360
371 Result_t readRegN(uint8_t devAddr, uint32_t reg, uint8_t *buf, uint32_t blen);
372
373 // Static implementations of the C++ class that can be used if you prefer a C style interface
374 static Result_t writeReg8(int module, uint8_t devAddr, uint32_t reg, uint8_t dat);
375 static Result_t readReg8(int module, uint8_t devAddr, uint32_t reg, uint8_t &dat);
376 static Result_t writeRegN(int module, uint8_t devAddr, uint32_t reg, const uint8_t *buf, uint32_t blen);
377 static Result_t readRegN(int module, uint8_t devAddr, uint32_t reg, uint8_t *buf, uint32_t blen);
378
379 void ShowStat(TxnStat s,const char * lab="");
380
381 // These functions are for internal use only.
382 void dump(uint32_t line);
383 friend void TWIHS0_Handler();
384 friend void TWIHS1_Handler();
385 friend void TWIHS2_Handler();
386
387 friend class WireIntf;
388 friend class TwoWire;
389
390}; // end class I2C
391
392
393// I2C instantions exist for all I2C (TWIHS) peripherals. They are accessed as array: i2c[0], i2c[1], i2c[2]
394extern I2C i2c[];
395
396inline I2C::Result_t I2C::writeReg8(int module, uint8_t devAddr, uint32_t reg, uint8_t dat)
397{
398 if (module < 0) { return I2C_RES_NACK; }
399 if (module > 2) { return I2C_RES_NACK; }
400 return i2c[module].writeReg8(devAddr, reg, dat);
401}
402
403inline I2C::Result_t I2C::readReg8(int module, uint8_t devAddr, uint32_t reg, uint8_t &dat)
404{
405 if (module < 0) { return I2C_RES_NACK; }
406 if (module > 2) { return I2C_RES_NACK; }
407 return i2c[module].readReg8(devAddr, reg, dat);
408}
409
410inline I2C::Result_t I2C::writeRegN(int module, uint8_t devAddr, uint32_t reg, const uint8_t *buf, uint32_t blen)
411{
412 if (module < 0) { return I2C_RES_NACK; }
413 if (module > 2) { return I2C_RES_NACK; }
414 return i2c[module].writeRegN(devAddr, reg, buf, blen);
415}
416inline I2C::Result_t I2C::readRegN(int module, uint8_t devAddr, uint32_t reg, uint8_t *buf, uint32_t blen)
417{
418 if (module < 0) { return I2C_RES_NACK; }
419 if (module > 2) { return I2C_RES_NACK; }
420 return i2c[module].readRegN(devAddr, reg, buf, blen);
421}
422
423
424/*-------------------------------------------------------------------------------------------------
425 * I2C Device Class
426 *------------------------------------------------------------------------------------------------*/
444
445private:
446 I2C *pI2CInterface; // Pointer to I2C class object for peripheral/interface
447 uint8_t devAddress; // I2C device address, 1 byte, 1 to 127
448 uint8_t numRegAddrBytes; // Number of register address bytes to send to device, 0 to 3
449
450public:
451
466 inline I2CDevice(I2C & pInterface, uint8_t deviceAddress, uint8_t numAddressBytes = 1)
467 {
468 pI2CInterface = &pInterface; // Pointer to the I2C peripheral module object
469 devAddress = deviceAddress; // Device I2C address
470 numRegAddrBytes = numAddressBytes; // Number of bytes to send for register address: 0 - 3
471 }
472
485 inline uint8_t getI2CAddress() { return devAddress; }
486
487
494 inline void setup(uint32_t busSpeed);
495
500 inline void resetBus();
501
502
511 inline I2C::Result_t writeReg8(uint32_t reg, uint8_t data)
512 {
513 pI2CInterface->setNumAddressBytes(numRegAddrBytes);
514 return pI2CInterface->writeReg8(devAddress, reg, data);
515 }
516
525 inline I2C::Result_t readReg8(uint32_t reg, uint8_t &data)
526 {
527 pI2CInterface->setNumAddressBytes(numRegAddrBytes);
528 return pI2CInterface->readReg8(devAddress, reg, data);
529 }
530
544 inline I2C::Result_t writeRegN(uint32_t reg, const uint8_t *buf, uint32_t blen)
545 {
546 pI2CInterface->setNumAddressBytes(numRegAddrBytes);
547 return pI2CInterface->writeRegN(devAddress, reg, buf, blen);
548 }
549
559 inline I2C::Result_t readRegN(uint32_t reg, uint8_t *buf, uint32_t blen)
560 {
561 pI2CInterface->setNumAddressBytes(numRegAddrBytes);
562 return pI2CInterface->readRegN(devAddress, reg, buf, blen);
563 }
564};
565
566
567
568#endif /* ----- #ifndef __I2C_H ----- */
569
I2C Device Class (recommended)
Definition i2c.h:443
I2CDevice(I2C &pInterface, uint8_t deviceAddress, uint8_t numAddressBytes=1)
Initialize the I2C module.
Definition i2c.h:466
void resetBus()
Reset the I2C bus.
uint8_t getI2CAddress()
Get device's I2C address.
Definition i2c.h:485
void setup(uint32_t busSpeed)
Setup the I2C peripheral module.
I2C::Result_t writeRegN(uint32_t reg, const uint8_t *buf, uint32_t blen)
Write a number of 8-bit values to an I2C slave to the specified register address.
Definition i2c.h:544
I2C::Result_t readReg8(uint32_t reg, uint8_t &data)
Read an 8-bit value form an I2C slave device register.
Definition i2c.h:525
I2C::Result_t writeReg8(uint32_t reg, uint8_t data)
Write an 8-bit value to an I2C slave device register.
Definition i2c.h:511
I2C::Result_t readRegN(uint32_t reg, uint8_t *buf, uint32_t blen)
Read a number of 8-bit values from an I2C slave at the specified register address.
Definition i2c.h:559
I2C Peripheral Class.
Definition i2c.h:213
void setup(uint32_t busSpeed)
Setup the I2C peripheral interface.
Result_t
Return result types.
Definition i2c.h:219
@ I2C_RES_NACK
Not acknowledged.
Definition i2c.h:221
@ I2C_RES_BUSY
Bus is busy.
Definition i2c.h:223
@ I2C_RES_ARB_LST
Arbitration listening.
Definition i2c.h:222
@ I2C_RES_ARG
Bad argument.
Definition i2c.h:224
@ I2C_RES_ACK
Acknowledged.
Definition i2c.h:220
Result_t readRegN(uint8_t devAddr, uint32_t reg, uint8_t *buf, uint32_t blen)
Read a number of 8-bit values from an I2C slave at the specified register address.
void setNumAddressBytes(uint8_t numAddressBytes=1)
Specify the register address size for a read or write transaction. A number of bytes,...
Definition i2c.h:321
Result_t readReg8(uint8_t devAddr, uint32_t reg, uint8_t &data)
Read an 8-bit value form an I2C slave device register.
void resetBus()
Reset the I2C bus.
Result_t writeRegN(uint8_t devAddr, uint32_t reg, const uint8_t *buf, uint32_t blen)
Write a number of 8-bit values to an I2C slave to the specified register address.
Result_t writeReg8(uint8_t devAddr, uint32_t reg, uint8_t data)
Write an 8-bit value to a I2C slave device register.
I2C(int module)
Constructor for the I2C peripheral module.
Result_t DoTransaction(I2CTxn_t *pTransaction, bool bRepeatedStart=false)
Start an I2C transaction.
Wire interface class.
Definition Wire.h:43
Wire Interface Class for I2C.
Definition i2c.h:66
uint8_t read()
Reads a byte of data that was transmitted from a slave I2C device after a call to requestFrom().
uint32_t write(char *str)
Queues bytes of data to be transmitted to the slave device. This function can be called after a call ...
void begin()
Initialize the WireIntf driver object as a master with a bus speed of 100 kHz. This normally only nee...
uint32_t write(uint8_t *buf, uint32_t len)
Queues bytes of data to be transmitted to the slave device. This function can be called after a call ...
void flush(bool bIssueStop=false)
Force the data that were queued to be transmitted using the write() functions to be transmitted on th...
void beginTransmission(uint8_t addr)
Begin a transmission to a I2C slave device at the provided address. Bytes can be queued for transmiss...
void endTransmission(bool stop=true)
Transmits the bytes of data queued by using the write() functions, and ends a transmission to a slave...
uint32_t requestFrom(uint8_t addr, uint32_t len, bool stop=true)
Request a number of bytes from a slave device. The bytes can then be retrieved from the slave device ...
uint32_t write(uint8_t dat)
Queues bytes of data to be transmitted to the slave device. This function can be called after a call ...
uint32_t available()
Get the number of bytes available to be read from the slave device with read(). This function can be ...