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