1////////////////////////////////////////////////////////////////////////////////
2// //
3// This software is supplied under the terms of a license agreement or //
4// nondisclosure agreement with Mitov Software and may not be copied //
5// or disclosed except in accordance with the terms of that agreement. //
6// Copyright(c) 2002-2016 Mitov Software. All Rights Reserved. //
7// //
8////////////////////////////////////////////////////////////////////////////////
9
10#ifndef _MITOV_MAXIM_MAX7300_h
11#define _MITOV_MAXIM_MAX7300_h
12
13#include <Mitov.h>
14#include <Mitov_Basic_GPIO.h>
15
16namespace Mitov
17{
18//---------------------------------------------------------------------------
19 class Maxim_MAX7300_Channel;
20//---------------------------------------------------------------------------
21 class Maxim_MAX7300 : public Mitov::EnableBasicGPIO<Mitov::EnabledComponent>
22 {
23 typedef Mitov::EnableBasicGPIO<Mitov::EnabledComponent> inherited;
24
25 public:
26 byte Address = 0;
27
28 protected:
29 bool FModifiedMap = false;
30 bool FModifiedPorts = false;
31 byte FConfigMap[ 7 ][ 2 ];
32 uint32_t FPorts[ 2 ];
33 uint32_t FReadMap = 0;
34 uint32_t FReadRegistersMap = 0;
35 uint32_t FReadBits;
36
37 protected:
38 void BeginTransmissionAt( byte ARegister )
39 {
40 byte AAddress = 0b01000000 | ( Address & 0b1111 );
41
42 Wire.beginTransmission( AAddress );
43
44 Wire.write( ARegister );
45 }
46
47 void WriteRegister( byte ARegister, byte AValue )
48 {
49// Serial.print( "WriteRegister: " ); Serial.print( ARegister ); Serial.print( " " ); Serial.println( AValue );
50
51 BeginTransmissionAt( ARegister );
52 Wire.write( AValue );
53 Wire.endTransmission();
54 }
55
56 virtual void UpdateEnable()
57 {
58 if( Enabled )
59 WriteRegister( 4, 1 );
60
61 else
62 WriteRegister( 4, 0 );
63
64 }
65
66 void UpdateConfigMap()
67 {
68// Serial.println( "UpdateConfigMap" );
69 bool AInUpdate = false;
70 for( int i = 0; i < 7; ++i )
71 {
72 if( FConfigMap[ i ][ 0 ] != FConfigMap[ i ][ 1 ] )
73 {
74 if( ! AInUpdate )
75 {
76// Serial.print( "BeginTransmissionAt: " ); Serial.println( 9 + i );
77 BeginTransmissionAt( 9 + i );
78 AInUpdate = true;
79 }
80
81// Serial.println( i );
82// Serial.println( FConfigMap[ i ][ 0 ] );
83
84 Wire.write( FConfigMap[ i ][ 0 ] );
85 FConfigMap[ i ][ 1 ] = FConfigMap[ i ][ 0 ];
86 }
87
88 else if( AInUpdate )
89 {
90 Wire.endTransmission();
91 AInUpdate = false;
92 }
93 }
94
95 if( AInUpdate )
96 Wire.endTransmission();
97
98 FReadRegistersMap = 0;
99 for( int i = 0; i <= 0x58 - 0x44; ++i )
100 if( FReadMap & ((uint32_t)0xFF) << i )
101 {
102 FReadRegistersMap |= ((uint32_t)1 ) << i;
103 i += 7;
104 }
105
106// Serial.print( "FReadRegistersMap: " ); Serial.println( FReadRegistersMap );
107
108 FModifiedMap = false;
109 }
110
111 void UpdatePorts()
112 {
113// Serial.println( "UpdatePorts" );
114// Serial.println( FPorts[ 0 ] );
115// Serial.println( FPorts[ 1 ] );
116 for( int i = 0; i < 28; ++i )
117 {
118 uint32_t AMask = ((uint32_t)1) << i;
119// Serial.println( AMask );
120 if( ( FPorts[ 0 ] & AMask ) != ( FPorts[ 1 ] & AMask ) )
121 {
122// Serial.println( i );
123// Serial.println( AMask );
124 WriteRegister( 0x44 + i, FPorts[ 0 ] >> i );
125 i += 8;
126// for( int j = i / 8; j < 4; j ++ )
127// WriteRegister( 0x44 + j * 8, FPorts[ 0 ] >> j * 8 );
128
129// break;
130 }
131 }
132
133 FPorts[ 1 ] = FPorts[ 0 ];
134 FModifiedPorts = false;
135 }
136
137 protected:
138 virtual void SystemStart()
139 {
140 inherited::SystemStart();
141 UpdateEnable();
142
143 for( int i = 0; i < 7; ++i )
144 FConfigMap[ i ][ 1 ] = ~FConfigMap[ i ][ 0 ];
145
146 FPorts[ 1 ] = ~FPorts[ 0 ];
147
148 UpdateConfigMap();
149 UpdatePorts();
150
151// UpdateOutput();
152 }
153
154 virtual void SystemLoopUpdateHardware()
155 {
156 if( FModifiedMap )
157// if( ! ClockInputPin.IsConnected() )
158 UpdateConfigMap();
159
160 if( FModifiedPorts )
161 UpdatePorts();
162
163 inherited::SystemLoopUpdateHardware();
164 }
165
166 public:
167 bool GetBitValue( uint32_t AIndex )
168 {
169 return( ( FReadBits & ( ((uint32_t)1 ) << AIndex )) != 0 );
170 }
171
172 void SetChannelValue( int AIndex, bool AValue )
173 {
174// AIndex += 4;
175
176// Serial.println( "SetChannelValue" );
177// Serial.println( AIndex );
178// Serial.println( AValue );
179
180 FPorts[ 0 ] &= ~( ((uint32_t)0b1 ) << AIndex );
181 FPorts[ 0 ] |= ( ((uint32_t)AValue ) & 1 ) << AIndex;
182 FModifiedPorts = true;
183 }
184
185 void SetChannelMode( int AIndex, int AMode )
186 {
187// AIndex += 4;
188
189// Serial.println( "SetChannelMode" );
190// Serial.println( AIndex );
191// Serial.println( AMode );
192
193 int AConfigIndex = AIndex / 4;
194 int AOffset = ( AIndex % 4 ) * 2;
195
196// Serial.println( AConfigIndex );
197// Serial.println( AOffset );
198
199 FConfigMap[ AConfigIndex ][ 0 ] &= ~( ((uint32_t)0b11) << AOffset );
200 FConfigMap[ AConfigIndex ][ 0 ] |= ((uint32_t)AMode) << AOffset;
201
202 if( AMode & 0b10 ) // Check if it is input
203 FReadMap |= ((uint32_t)1) << AIndex;
204
205 else
206 FReadMap &= ~( ((uint32_t)1) << AIndex );
207
208 FModifiedMap = true;
209 }
210
211 protected:
212 virtual void PerformRead()
213 {
214 if( ! FReadRegistersMap)
215 return;
216
217 FReadBits = 0;
218 for( int i = 0; i <= 0x58 - 0x44; ++i )
219 if( (((uint32_t)1 ) << i ) & FReadRegistersMap )
220 {
221 BeginTransmissionAt( 0x44 + i );
222 Wire.endTransmission();
223 Wire.requestFrom( 0b01000000 | ( Address & 0b1111 ), 1 );
224 while (Wire.available() < 1 );
225
226 uint32_t ARegister = Wire.read();
227
228 FReadBits |= ARegister << i;
229
230// Serial.print( i ); Serial.print( ": " ); Serial.println( ARegister );
231
232 i += 7;
233 }
234
235 for( int i = 0; i < inherited::FChannels.size(); ++i )
236 inherited::FChannels[ i ]->UpdateInput();
237
238 }
239
240 public:
241 Maxim_MAX7300()
242 {
243 for( int i = 0; i < 7; ++i )
244 FConfigMap[ i ][ 0 ] = 0b10101010;
245 }
246
247 };
248//---------------------------------------------------------------------------
249 class Maxim_MAX7300_Channel : public OwnedBasicGPIOChannel<Maxim_MAX7300>
250 {
251 typedef OwnedBasicGPIOChannel<Maxim_MAX7300> inherited;
252
253
254 public:
255 virtual void UpdateInput()
256 {
257 UpdateOutput( FOwner.GetBitValue( FIndex ));
258 }
259
260 protected:
261 virtual void PinDirectionsInit()
262 {
263 if( FIsOutput )
264 {
265 FOwner.SetChannelMode( FIndex, 1 ); //pinMode( FPinNumber, OUTPUT );
266 FOwner.SetChannelValue( FIndex, FValue );
267 }
268
269 else
270 {
271 if( FIsPullUp )
272 FOwner.SetChannelMode( FIndex, 3 ); //pinMode( FPinNumber, INPUT_PULLUP );
273
274 else
275 FOwner.SetChannelMode( FIndex, 2 ); //pinMode( FPinNumber, INPUT );
276 }
277 }
278
279 public:
280 Maxim_MAX7300_Channel( Maxim_MAX7300 &AOwner, int AIndex, bool AInitialValue, bool AIsOutput, bool AIsPullUp, bool AIsCombinedInOut ) :
281 inherited( AOwner, AIndex, AInitialValue, AIsOutput, AIsPullUp, AIsCombinedInOut )
282 {
283 PinDirectionsInit();
284 }
285
286 };
287//---------------------------------------------------------------------------
288}
289
290#endif