1 /*
2    Copyright (C) 2006 Scott Dattalo
3 
4 This file is part of the libgpsim_modules library of gpsim
5 
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10 
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 */
20 
21 #ifndef MODULES_I2C_H_
22 #define MODULES_I2C_H_
23 
24 #include "../src/gpsim_classes.h"
25 #include "../src/modules.h"
26 #include "../src/trigger.h"
27 
28 class IO_open_collector;
29 
30 namespace I2C_Module {
31 
32 //------------------------------------------------------------------------
33 // I2C Attributes
34 class  I2C_TxBuffer;
35 class  I2C_TxReady;
36 class  I2C_RxBuffer;
37 class  I2C_RxSequence;
38 class  I2C_Send7BitAddress;
39 class  I2C_Stop;
40 class  I2C_Address;
41 class  I2C_Debug;
42 class  I2CMasterModule;
43 
44 
45 //------------------------------------------------------------------------
46 // I2C interface
47 //
48 // The pure virtual I2C interface class is used by the I2CMaster
49 // class to establish low-level communications.
50 class I2CInterface {
51 public:
~I2CInterface()52   virtual ~I2CInterface()
53   {
54   }
55 
56   static  void *master_interface(void *);
57   virtual void run_tests() = 0;
58 };
59 
60 
61 //------------------------------------------------------------------------
62 // I2CMaster
63 //
64 // The I2CMaster can either a) simulate a master interface or b) provide support
65 // for some external code that wishes to serve as a master.
66 
67 
68 class I2CMaster : public TriggerObject, public Module {
69 public:
70   explicit I2CMaster(const char *_name);
71   virtual ~I2CMaster();
72 
73   static Module *construct(const char *new_name);
74   virtual void create_iopin_map();
75 
76   void reset(RESET_TYPE);
77   enum eI2CResult {
78     eI2CResAck,       // Slave acknowledged last transfer
79     eI2CResNack,      // Slave did not acknowledge last transfer
80     eI2CResSuccess,   // Last action succeeded
81     eI2CResFailed,    // Last action failed.
82     eI2CResCollision, //
83   };
84 
85   /// There are only three things the I2CMaster hardware knows how
86   /// to do: send start bits, send stop bits, transfer 8 data bits.
87   /// Note that a read operation is performed when the byte '0xff'
88   /// is written.
89 
90   eI2CResult sendStart();
91   eI2CResult sendStop();
92   eI2CResult send8BitData(unsigned int data);
93   void send7BitAddress(unsigned addr);
94 
95   /// rising and falling SCL and SDA edges are captured:
96 
97   void new_scl_edge(bool direction);
98   void new_sda_edge(bool direction);
99 
100   /// Breakpoint stuff
101   virtual void callback();
102   virtual void callback_print();
bpName()103   virtual char const * bpName()
104   {
105     return "i2cmaster";
106   }
107 
108   /// When the start, stop or transfer state machines then these
109   /// functions are called. (Classes derived from this one can
110   /// capture this).
111   virtual void startCompleted();
112   virtual void stopCompleted();
113   virtual void transferCompleted();
114 
115   void debug();
116 
117   /// I/O pins for the I2C bus
118 
119   IO_open_collector *m_pSCL;
120   IO_open_collector *m_pSDA;
121 
122 protected:
123   void wait_uSec(unsigned int uSec);
124   void startIdle();
125   bool checkSDA_SCL(bool bSDA, bool bSCL);
126 
127   unsigned int m_bitCount;   // Current bit number for either Tx or Rx
128   unsigned int m_command;    // Most recent command received from I2C host
129   unsigned int m_xfr_data;   // Transmit and receive shift register.
130   unsigned int m_TxData;     // Next data byte to transmit
131   bool         m_nextBit;    // Next bit to be sent
132 
133   guint64 future_cycle;
134 
135   I2CMasterModule *m_pI2CModule;
136 
137 private:
138   enum eI2CMicroState {
139     eI2CIdle = 0,
140 
141     // Micro states for Start
142 
143     eI2CStartA,       // Trying to drive SDA low to begin start
144     eI2CStartB,       // Holding Start state  (SDA=0, SCL=1)
145     eI2CStartC,       // Holding Start state  (SDA=0, SCL=0)
146     eI2CListenToAddress, // Some other master initiated a start.
147     eI2CBusy,            // Some other Master has control of the bus.
148 
149     // Micro states for Transfer
150     eI2CTransferA,       // Transfer- drove SCL low, waiting for it to fall
151     eI2CTransferB,       // Transfer- caught SCL low, waiting to update SDA
152     eI2CTransferC,       // Transfer- update SDA, wait to drive SCL high
153     eI2CTransferD,       // Transfer- drive SCL high, waiting for it to rise
154     eI2CTransferE,       // Transfer- caught SCL high, wait before driving low
155 
156     // Micro states for Stop
157     eI2CStopA,           // Stop - Waiting to drive SDA high.
158     eI2CStopB,           // Stop - drove SDA high Waiting for it to go high.
159 
160   } m_uState;
161 
162   enum eI2CMacroState {
163     //eI2CStart,           // In the process of sending a start bit.
164     eI2CStop,            // In the process of sending a stop bit
165     eI2CTransfer,        // In the prcoess of transferring a byte
166     eI2CMaster,          // Bus is idle but we're in control.
167     eI2CSlave,           // Bus is idle but we're not in control
168     eI2CIdleBus          // Bus is idle and no one owns it
169 
170   } m_mState;
171 
172   const unsigned int m_MSBmask;   // MSB of transfer mask. Used in data transfers
173   bool readBit();
174   void setNextMicroState(eI2CMicroState nextState, unsigned int waitTime);
175   void setNextMacroState(eI2CMacroState nextState);
176   // Define propogation delays.
177 
178   // tClkToData = time between when the I2C clock goes
179   // low and when the I2C module will update it's data
180   // output line.
181 
182   unsigned int tClkToData;
183 
184   // tClkToSample - time between when the I2C clock goes
185   // low and when the I2C module will sample the data
186   // line.
187   unsigned int tClkToSample;
188 
189   /// token - the I2C master interfaces to the I2C client. The
190   /// client runs in a different thread. token synchronizes the
191   /// two threads.
192 
193   // gpsim::Token token; not implemented...
194 
195   /// debug stuff
196   const char *microStateName(eI2CMicroState);
197   const char *macroStateName(eI2CMacroState);
198 
199   /// I2C attribute for the Transmit buffer. Writing a byte to
200   /// this attribute initiates an I2C transmit.
201   I2C_TxBuffer   *mTxByte;
202 
203   /// I2C attribute for transmit ready status. 'true' means the module
204   /// is ready to transmit.
205 
206   I2C_TxReady    *mTxReady;
207 
208   /// I2C Receive buffer. This holds the last byte received.
209 
210   I2C_RxBuffer   *mRxByte;
211 
212   /// I2C Receive Sequence number. This increments everytime a byte is
213   /// received.
214 
215   I2C_RxSequence *mRxSequence;
216 
217   /// I2C 7-bit Address: Writing to here initiates an I2C transaction
218   I2C_Send7BitAddress *mSend7BitAddress;
219 
220   /// I2C 10-bit Address: Writing to here initiates an I2C transaction
221   //I2C_Send10BitAddress *mSend10BitAddress;
222 
223   /// I2C Stop. Complete current transfer then issue a STOP bit
224   I2C_Stop *mStop;
225 
226   /// I2C Module's address
227   I2C_Address *mAddress;
228 
229   /// I2C debug
230   I2C_Debug *mDebug;
231 };
232 
233 }  // end of namespace
234 
235 
236 #endif // MODULES_I2C_H_
237 
238