AceTMI  0.2.0
Unified interface for selecting different implementations for communicating with a TM1637 LED controller chip on Arduino platforms
SimpleTmiInterface.h
1 /*
2 MIT License
3 
4 Copyright (c) 2021 Brian T. Park
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
25 #ifndef ACE_TMI_SIMPLE_TMI_INTERFACE_H
26 #define ACE_TMI_SIMPLE_TMI_INTERFACE_H
27 
28 #include <Arduino.h>
29 
30 namespace ace_tmi {
31 
64  public:
78  uint8_t dioPin,
79  uint8_t clkPin,
80  uint8_t delayMicros
81  ) :
82  mDioPin(dioPin),
83  mClkPin(clkPin),
84  mDelayMicros(delayMicros)
85  {}
86 
96  void begin() const {
97  digitalWrite(mClkPin, LOW);
98  digitalWrite(mDioPin, LOW);
99 
100  // Begin with both lines at HIGH.
101  clockHigh();
102  dataHigh();
103  }
104 
106  void end() const {
107  clockHigh();
108  dataHigh();
109  }
110 
112  void startCondition() const {
113  clockHigh();
114  dataHigh();
115 
116  dataLow();
117  clockLow();
118  }
119 
121  void stopCondition() const {
122  // clock will always be LOW when this is called
123  dataLow();
124  clockHigh();
125  dataHigh();
126  }
127 
139  uint8_t sendByte(uint8_t data) const {
140  for (uint8_t i = 0; i < 8; ++i) {
141  if (data & 0x1) {
142  dataHigh();
143  } else {
144  dataLow();
145  }
146  clockHigh();
147  // An extra bitDelay() here would make the HIGH and LOW states symmetric
148  // in duration (if digitalWrite() is assumed to be infinitely fast,
149  // which it is definitely not). But actual devices that I have tested
150  // seem to support the absence of that extra delay. So let's ignore it
151  // to make the transfer speed faster.
152  clockLow();
153  data >>= 1;
154  }
155 
156  uint8_t ack = readAck();
157  return ack ^ 0x1; // invert the 0 and 1
158  }
159 
160  // Use default copy constructor and assignment operator.
161  SimpleTmiInterface(const SimpleTmiInterface&) = default;
162  SimpleTmiInterface& operator=(const SimpleTmiInterface&) = default;
163 
164  private:
171  uint8_t readAck() const {
172  // Go into INPUT mode, reusing dataHigh(), saving 10 flash bytes on AVR.
173  dataHigh();
174 
175  // DIO is supposed to remain stable after CLK is set HIGH.
176  clockHigh();
177 
178  uint8_t ack = digitalRead(mDioPin);
179 
180  // Device releases DIO upon falling edge of the 9th CLK.
181  clockLow();
182  return ack;
183  }
184 
185  void bitDelay() const { delayMicroseconds(mDelayMicros); }
186 
187  void clockHigh() const { pinMode(mClkPin, INPUT); bitDelay(); }
188 
189  void clockLow() const { pinMode(mClkPin, OUTPUT); bitDelay(); }
190 
191  void dataHigh() const { pinMode(mDioPin, INPUT); bitDelay(); }
192 
193  void dataLow() const { pinMode(mDioPin, OUTPUT); bitDelay(); }
194 
195  private:
196  uint8_t const mDioPin;
197  uint8_t const mClkPin;
198  uint8_t const mDelayMicros;
199 };
200 
201 } // ace_tmi
202 
203 #endif
ace_tmi::SimpleTmiInterface::stopCondition
void stopCondition() const
Generate the I2C stop condition.
Definition: SimpleTmiInterface.h:121
ace_tmi::SimpleTmiInterface::begin
void begin() const
Initialize the dio and clk pins.
Definition: SimpleTmiInterface.h:96
ace_tmi::SimpleTmiInterface
Class that knows how to communicate with a TM1637 chip.
Definition: SimpleTmiInterface.h:63
ace_tmi::SimpleTmiInterface::sendByte
uint8_t sendByte(uint8_t data) const
Send the data byte on the data bus, with LSB first instead of the usual MSB first for I2C.
Definition: SimpleTmiInterface.h:139
ace_tmi::SimpleTmiInterface::end
void end() const
Set dio and clk pins to INPUT mode.
Definition: SimpleTmiInterface.h:106
ace_tmi::SimpleTmiInterface::SimpleTmiInterface
SimpleTmiInterface(uint8_t dioPin, uint8_t clkPin, uint8_t delayMicros)
Constructor.
Definition: SimpleTmiInterface.h:77
ace_tmi::SimpleTmiInterface::startCondition
void startCondition() const
Generate the I2C start condition.
Definition: SimpleTmiInterface.h:112