libraries / Mitov / Mitov_Maxim_MAX7300.hon commit Added link to project report (97a3ba0)
   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