Class for representing and controlling entire I2C transactions (the master side). This class allows one to separate in code the configuration of I2C transactions from their use. This property simplifies the process of executing transactions in, for example, the body of a real-time control loop.

Committer:
symbiotic
Date:
Wed May 21 21:12:32 2014 +0000
Revision:
0:96a7926b9d64
Child:
1:5d9e9c0682f0
Child:
2:19e7e472a51f
Original released version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
symbiotic 0:96a7926b9d64 1 #include "I2CTransaction.h"
symbiotic 0:96a7926b9d64 2
symbiotic 0:96a7926b9d64 3 /**
symbiotic 0:96a7926b9d64 4 I2C Transaction Class.
symbiotic 0:96a7926b9d64 5
symbiotic 0:96a7926b9d64 6 Author: Andrew H. Fagg (May, 2014)
symbiotic 0:96a7926b9d64 7
symbiotic 0:96a7926b9d64 8 TODO: finish this description
symbiotic 0:96a7926b9d64 9
symbiotic 0:96a7926b9d64 10 This class provides:
symbiotic 0:96a7926b9d64 11 - Interrupt-driven I2C master functionality
symbiotic 0:96a7926b9d64 12 - Representations of whole transactions
symbiotic 0:96a7926b9d64 13
symbiotic 0:96a7926b9d64 14 I2C Transactions generally come in two varieties: a write and a write followed by a read
symbiotic 0:96a7926b9d64 15
symbiotic 0:96a7926b9d64 16
symbiotic 0:96a7926b9d64 17
symbiotic 0:96a7926b9d64 18 Notes:
symbiotic 0:96a7926b9d64 19 I2C Status codes:
symbiotic 0:96a7926b9d64 20 - 32: write NO-ACK
symbiotic 0:96a7926b9d64 21 - 72: read NO-ACK
symbiotic 0:96a7926b9d64 22 - 40: write ACK
symbiotic 0:96a7926b9d64 23 - 88: read ACK
symbiotic 0:96a7926b9d64 24 */
symbiotic 0:96a7926b9d64 25
symbiotic 0:96a7926b9d64 26 // Initialization of static member (kind of gross to do it this way)
symbiotic 0:96a7926b9d64 27 //MODI2C* I2CTransaction::i2c = new MODI2C(p9, p10);
symbiotic 0:96a7926b9d64 28 MODI2C* I2CTransaction::i2c = new MODI2C(p28, p27);
symbiotic 0:96a7926b9d64 29
symbiotic 0:96a7926b9d64 30 /**
symbiotic 0:96a7926b9d64 31 Transaction constructor
symbiotic 0:96a7926b9d64 32
symbiotic 0:96a7926b9d64 33 @param I2C address (7-bit address)
symbiotic 0:96a7926b9d64 34 @param writePacket Pointer to the data structure to be written
symbiotic 0:96a7926b9d64 35 @param writePacketLength Number of bytes to be written
symbiotic 0:96a7926b9d64 36 @param readPacket Pointer to the data structure to be filled during the read (NULL = none)
symbiotic 0:96a7926b9d64 37 @param readPacketLength Number of bytes to read
symbiotic 0:96a7926b9d64 38 */
symbiotic 0:96a7926b9d64 39
symbiotic 0:96a7926b9d64 40 I2CTransaction::I2CTransaction(int address, char* writePacket, int writePacketLength, char* readPacket, int readPacketLength)
symbiotic 0:96a7926b9d64 41 {
symbiotic 0:96a7926b9d64 42 this->address = address;
symbiotic 0:96a7926b9d64 43 this->writePacket = writePacket;
symbiotic 0:96a7926b9d64 44 this->writePacketLength = writePacketLength;
symbiotic 0:96a7926b9d64 45 this->readPacket = readPacket;
symbiotic 0:96a7926b9d64 46 this->readPacketLength = readPacketLength;
symbiotic 0:96a7926b9d64 47 if(readPacket == NULL) this->readPacketLength = 0;
symbiotic 0:96a7926b9d64 48 status[0] = status[1] = -1;
symbiotic 0:96a7926b9d64 49 }
symbiotic 0:96a7926b9d64 50
symbiotic 0:96a7926b9d64 51 /**
symbiotic 0:96a7926b9d64 52 Set the I2C bus frequency
symbiotic 0:96a7926b9d64 53
symbiotic 0:96a7926b9d64 54 @param frequency in Hertz
symbiotic 0:96a7926b9d64 55 */
symbiotic 0:96a7926b9d64 56
symbiotic 0:96a7926b9d64 57 void I2CTransaction::setFrequency(int frequency)
symbiotic 0:96a7926b9d64 58 {
symbiotic 0:96a7926b9d64 59 i2c->frequency(frequency);
symbiotic 0:96a7926b9d64 60 }
symbiotic 0:96a7926b9d64 61
symbiotic 0:96a7926b9d64 62 /**
symbiotic 0:96a7926b9d64 63 Indicate whether the transaction has completed (whether successful or not)
symbiotic 0:96a7926b9d64 64
symbiotic 0:96a7926b9d64 65 Note: assumes that for the case with no read part of the transaction, status[1]
symbiotic 0:96a7926b9d64 66 has been left in its initial state (-1)
symbiotic 0:96a7926b9d64 67 */
symbiotic 0:96a7926b9d64 68
symbiotic 0:96a7926b9d64 69 bool I2CTransaction::completed()
symbiotic 0:96a7926b9d64 70 {
symbiotic 0:96a7926b9d64 71 return(status[0] != 0 && status[1] != 0);
symbiotic 0:96a7926b9d64 72 }
symbiotic 0:96a7926b9d64 73
symbiotic 0:96a7926b9d64 74 /**
symbiotic 0:96a7926b9d64 75 Return the specified status code for this transaction
symbiotic 0:96a7926b9d64 76
symbiotic 0:96a7926b9d64 77 @param i 0 = write status code; 1 = read status code
symbiotic 0:96a7926b9d64 78 @return Status code (see documentation at top of this file)
symbiotic 0:96a7926b9d64 79 */
symbiotic 0:96a7926b9d64 80
symbiotic 0:96a7926b9d64 81 int I2CTransaction::getStatus(int i)
symbiotic 0:96a7926b9d64 82 {
symbiotic 0:96a7926b9d64 83 if(i >= 0 && i <= 1) return status[i];
symbiotic 0:96a7926b9d64 84 else return -1;
symbiotic 0:96a7926b9d64 85 }
symbiotic 0:96a7926b9d64 86
symbiotic 0:96a7926b9d64 87 /**
symbiotic 0:96a7926b9d64 88 Start a transaction.
symbiotic 0:96a7926b9d64 89
symbiotic 0:96a7926b9d64 90 Does not initiate a transaction if it is already in progress.
symbiotic 0:96a7926b9d64 91
symbiotic 0:96a7926b9d64 92 Note: no error checking yet on the read and write calls
symbiotic 0:96a7926b9d64 93
symbiotic 0:96a7926b9d64 94 @return true if transaction has been initiated; false if it is already in progress
symbiotic 0:96a7926b9d64 95 */
symbiotic 0:96a7926b9d64 96
symbiotic 0:96a7926b9d64 97 bool I2CTransaction::initiateTransaction()
symbiotic 0:96a7926b9d64 98 {
symbiotic 0:96a7926b9d64 99 if(!completed()) {
symbiotic 0:96a7926b9d64 100 // Already in progress: bail
symbiotic 0:96a7926b9d64 101 return false;
symbiotic 0:96a7926b9d64 102 } else {
symbiotic 0:96a7926b9d64 103 // Start the write
symbiotic 0:96a7926b9d64 104 i2c->write(address << 1, writePacket, writePacketLength, false, &(status[0]));
symbiotic 0:96a7926b9d64 105
symbiotic 0:96a7926b9d64 106 // Start the read if it exists
symbiotic 0:96a7926b9d64 107 if(readPacket != NULL) {
symbiotic 0:96a7926b9d64 108 i2c->read_nb(address << 1, readPacket, readPacketLength, false, &(status[1]));
symbiotic 0:96a7926b9d64 109 }
symbiotic 0:96a7926b9d64 110 return true;
symbiotic 0:96a7926b9d64 111 }
symbiotic 0:96a7926b9d64 112 }
symbiotic 0:96a7926b9d64 113
symbiotic 0:96a7926b9d64 114 /**
symbiotic 0:96a7926b9d64 115 Wait until the transaction has completed, up to the specified number of milliseconds
symbiotic 0:96a7926b9d64 116
symbiotic 0:96a7926b9d64 117 @param timeout Number of milliseconds to wait
symbiotic 0:96a7926b9d64 118
symbiotic 0:96a7926b9d64 119 @return true if transaction completed; false if timed out
symbiotic 0:96a7926b9d64 120 */
symbiotic 0:96a7926b9d64 121
symbiotic 0:96a7926b9d64 122 bool I2CTransaction::waitForCompletion(int timeout)
symbiotic 0:96a7926b9d64 123 {
symbiotic 0:96a7926b9d64 124 for(int i = 0; i < timeout; ++i) {
symbiotic 0:96a7926b9d64 125 if(this->completed()) return true;
symbiotic 0:96a7926b9d64 126 wait_ms(1);
symbiotic 0:96a7926b9d64 127 }
symbiotic 0:96a7926b9d64 128 return(false);
symbiotic 0:96a7926b9d64 129 }
symbiotic 0:96a7926b9d64 130
symbiotic 0:96a7926b9d64 131 /**
symbiotic 0:96a7926b9d64 132 Display the transaction status codes
symbiotic 0:96a7926b9d64 133
symbiotic 0:96a7926b9d64 134 @param pc Pointer to an initialized serial handler
symbiotic 0:96a7926b9d64 135 @param strg String description of this transaction
symbiotic 0:96a7926b9d64 136 */
symbiotic 0:96a7926b9d64 137
symbiotic 0:96a7926b9d64 138 void I2CTransaction::displayStatus(Serial *pc, char* strg)
symbiotic 0:96a7926b9d64 139 {
symbiotic 0:96a7926b9d64 140 if(readPacket == NULL) {
symbiotic 0:96a7926b9d64 141 // Write only
symbiotic 0:96a7926b9d64 142 pc->printf("%s\t%d\n\r", strg, status[0]);
symbiotic 0:96a7926b9d64 143 } else {
symbiotic 0:96a7926b9d64 144 // Write - Read
symbiotic 0:96a7926b9d64 145 pc->printf("%s\t%d\t%d\n\r", strg, status[0], status[1]);
symbiotic 0:96a7926b9d64 146 }
symbiotic 0:96a7926b9d64 147 }
symbiotic 0:96a7926b9d64 148
symbiotic 0:96a7926b9d64 149 /**
symbiotic 0:96a7926b9d64 150 Check that the transaction was successfully completed.
symbiotic 0:96a7926b9d64 151
symbiotic 0:96a7926b9d64 152 @return true if successful, false if not
symbiotic 0:96a7926b9d64 153 */
symbiotic 0:96a7926b9d64 154
symbiotic 0:96a7926b9d64 155 bool I2CTransaction::success()
symbiotic 0:96a7926b9d64 156 {
symbiotic 0:96a7926b9d64 157 // Write transaction must have completed with the correct status code (40)
symbiotic 0:96a7926b9d64 158 // Read transaction, if it exists, must also complete correctly (88)
symbiotic 0:96a7926b9d64 159 return (status[0] == 40) && (readPacket == NULL || status[1] == 88);
symbiotic 0:96a7926b9d64 160 }
symbiotic 0:96a7926b9d64 161
symbiotic 0:96a7926b9d64 162
symbiotic 0:96a7926b9d64 163 /**
symbiotic 0:96a7926b9d64 164 Check that the transaction has an error
symbiotic 0:96a7926b9d64 165
symbiotic 0:96a7926b9d64 166 @return true if error, false if not
symbiotic 0:96a7926b9d64 167 */
symbiotic 0:96a7926b9d64 168
symbiotic 0:96a7926b9d64 169 bool I2CTransaction::error()
symbiotic 0:96a7926b9d64 170 {
symbiotic 0:96a7926b9d64 171 // Write transaction has completed with an error code (can't be 0 (in progress) or 40 (correct))
symbiotic 0:96a7926b9d64 172 // Read transaction, if it exists, has completed with an error code (can't be 0 (in progress) or 88 (correct))
symbiotic 0:96a7926b9d64 173 return (status[0] != 0 && status[0] != 40) || (readPacket != NULL && status[1] != 0 && status[1] != 88);
symbiotic 0:96a7926b9d64 174 }