libraries / Mitov / Mitov_Potentiometer_SPI.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_POTENTIOMETER_SPI_h
  11#define _MITOV_POTENTIOMETER_SPI_h
  12
  13#include <Mitov.h>
  14#include <Mitov_Basic_SPI.h>
  15
  16namespace Mitov
  17{
  18//---------------------------------------------------------------------------
  19        class PotentiometerSPIChannel;
  20//---------------------------------------------------------------------------
  21        class Potentiometer_SPI : public Mitov::Basic_MultiChannel_SourceSPI
  22        {
  23                typedef Mitov::Basic_MultiChannel_SourceSPI inherited;
  24
  25        protected:
  26                static const uint8_t kADR_WIPER0       = B00000000;
  27                static const uint8_t kADR_WIPER1       = B00010000;
  28
  29                static const uint8_t kCMD_READ         = B00001100;
  30            static const uint8_t kCMD_WRITE        = B00000000;
  31
  32            static const uint8_t kADR_VOLATILE     = B00000000;
  33                static const uint8_t kADR_NON_VOLATILE = B00100000;
  34
  35                static const uint8_t kTCON_REGISTER    = B01000000;
  36                static const uint8_t kSTATUS_REGISTER  = B01010000;
  37
  38        protected:
  39                uint16_t byte2uint16(byte high_byte, byte low_byte)
  40                {
  41                        return (uint16_t)high_byte<<8 | (uint16_t)low_byte;
  42                }
  43
  44        public:
  45                void    SetEnabled( bool AValue )
  46                {
  47                        if( Enabled == AValue )
  48                                return;
  49
  50                        Enabled = AValue;
  51                        for( int i =0; i < FChannels.size(); ++i )
  52                                FChannels[ i ]->InitChannel();
  53                }
  54
  55        public:
  56                void SPI_write(byte cmd_byte, byte data_byte)
  57                {
  58                        cmd_byte |= kCMD_WRITE;
  59                        ChipSelectOutputPin.SendValue( false );
  60                        FSPI.transfer(cmd_byte);
  61                        FSPI.transfer(data_byte);
  62                        ChipSelectOutputPin.SendValue( true );
  63                }
  64
  65                uint16_t SPI_read(byte cmd_byte)
  66                {
  67                        cmd_byte |= kCMD_READ;
  68                        ChipSelectOutputPin.SendValue( false );
  69                        byte high_byte = FSPI.transfer(cmd_byte);
  70                        byte low_byte  = FSPI.transfer(0xFF);
  71                        ChipSelectOutputPin.SendValue( true );
  72                        return byte2uint16(high_byte, low_byte);                
  73                }
  74
  75        public:
  76                using inherited::inherited;
  77
  78        };
  79//---------------------------------------------------------------------------
  80        class PotentiometerSPIChannel : public Mitov::Basic_Typed_SPIChannel<Potentiometer_SPI>
  81        {
  82                typedef Mitov::Basic_Typed_SPIChannel<Potentiometer_SPI>        inherited;
  83
  84        public:
  85                bool    Enabled = true;
  86
  87                bool    ConnectTerminalA = true;
  88                bool    ConnectWiper = true;
  89                bool    ConnectTerminalB = true;
  90                bool    NonVolatile = false;
  91
  92        protected:
  93                int             FMultiplier;
  94
  95        public:
  96                virtual void InitChannel()
  97                {
  98                        uint16_t ATerminalControlValue = FOwner.SPI_read( 4 );
  99                        uint16_t ANewValue;
 100                        if( ConnectTerminalB )
 101                                ANewValue = 1;
 102
 103                        else
 104                                ANewValue = 0;
 105
 106                        if( ConnectWiper )
 107                                ANewValue |= B10;
 108
 109                        if( ConnectTerminalA )
 110                                ANewValue |= B100;
 111
 112                        if( ! Enabled )
 113                                ANewValue |= B1000;
 114
 115                        if( FIndex == 1 )
 116                        {
 117                                ATerminalControlValue &= 0xFF0F;
 118                                ATerminalControlValue |= ( ANewValue << 4 );
 119                        }
 120                        else
 121                        {
 122                                ATerminalControlValue &= 0xFFF0;
 123                                ATerminalControlValue |= ANewValue;
 124                        }
 125
 126                        FOwner.SPI_write( 4, ATerminalControlValue );
 127                }
 128
 129                virtual void SendOutput()
 130                {
 131                        if( FNewValue == FValue )
 132                                return;
 133
 134                        int wiper_pos = ( FValue * FMultiplier );
 135
 136                        wiper_pos = constrain( wiper_pos, 0, FMultiplier );
 137
 138                        FValue = FNewValue;
 139                        byte data_byte;
 140                        byte cmd_byte = FIndex;
 141
 142                        // Calculate the 9-bit data value to send
 143                        data_byte = (byte)(wiper_pos & 0x00FF);
 144                        if(wiper_pos > FMultiplier - 1)
 145                                if( FMultiplier == 256 )
 146                                        cmd_byte |= B00000001; // Table 5-1 (page 36)
 147
 148                        FOwner.SPI_write( cmd_byte, data_byte );
 149
 150                        if( NonVolatile )
 151                        {
 152                                // EEPROM write cycles take 4ms each. So we block with delay(5); after any NV Writes
 153                                FOwner.SPI_write( cmd_byte | B10, data_byte );
 154                                delay(5);
 155                        }
 156                }
 157
 158        public:
 159                void    SetEnabled( bool AValue )
 160                {
 161                        if( Enabled == AValue )
 162                                return;
 163
 164                        Enabled = AValue;
 165                        InitChannel();
 166                }
 167
 168                void    SetConnectTerminalA( bool AValue )
 169                {
 170                        if( ConnectTerminalA == AValue )
 171                                return;
 172
 173                        ConnectTerminalA = AValue;
 174                        InitChannel();
 175                }
 176
 177                void    SetConnectWiper( bool AValue )
 178                {
 179                        if( ConnectWiper == AValue )
 180                                return;
 181
 182                        ConnectWiper = AValue;
 183                        InitChannel();
 184                }
 185
 186                void    SetConnectTerminalB( bool AValue )
 187                {
 188                        if( ConnectTerminalB == AValue )
 189                                return;
 190
 191                        ConnectTerminalB = AValue;
 192                        InitChannel();
 193                }
 194
 195                void    SetNonVolatile( bool AValue )
 196                {
 197                        if( NonVolatile == AValue )
 198                                return;
 199
 200                        NonVolatile = AValue;
 201                        InitChannel();
 202                }
 203
 204        public:
 205                PotentiometerSPIChannel( Potentiometer_SPI &AOwner, int AIndex, int AMultiplier ) :
 206                        inherited( AOwner, AIndex ),
 207                        FMultiplier( AMultiplier )
 208                {
 209                }
 210
 211        };
 212//---------------------------------------------------------------------------
 213}
 214
 215#endif