AceSegment  0.7.0
A framework for rendering seven segment LED displays using the TM1637, MAX7219, HT16K33, or 74HC595 controller chips
SoftTmiInterface.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_SEGMENT_SOFT_TMI_INTERFACE_H
26 #define ACE_SEGMENT_SOFT_TMI_INTERFACE_H
27 
28 #include <Arduino.h>
29 
30 namespace ace_segment {
31 
66  public:
74  explicit SoftTmiInterface(
75  uint8_t dioPin,
76  uint8_t clkPin,
77  uint8_t delayMicros
78  ) :
79  mDioPin(dioPin),
80  mClkPin(clkPin),
81  mDelayMicros(delayMicros)
82  {}
83 
85  void begin() const {
86  // These are open-drain lines, with a pull-up resistor. We must not drive
87  // them HIGH actively since that could damage the transitor at the other
88  // end of the line pulling LOW. Instead, we go into INPUT mode to let the
89  // line to HIGH through the pullup resistor, then go to OUTPUT mode only
90  // to pull down.
91  digitalWrite(mClkPin, LOW);
92  digitalWrite(mDioPin, LOW);
93 
94  // Begin with both lines at HIGH.
95  clockHigh();
96  dataHigh();
97  }
98 
100  void end() const {
101  clockHigh();
102  dataHigh();
103  }
104 
106  void startCondition() const {
107  clockHigh();
108  dataHigh();
109 
110  dataLow();
111  clockLow();
112  }
113 
115  void stopCondition() const {
116  dataLow();
117  clockHigh();
118  dataHigh();
119  }
120 
127  uint8_t sendByte(uint8_t data) const {
128  for (uint8_t i = 0; i < 8; ++i) {
129  if (data & 0x1) {
130  dataHigh();
131  } else {
132  dataLow();
133  }
134  clockHigh();
135  clockLow();
136  data >>= 1;
137  }
138 
139  return readAck();
140  }
141 
142  private:
147  uint8_t readAck() const {
148  // Go into INPUT mode, reusing dataHigh(), saving 10 flash bytes on AVR.
149  dataHigh();
150  uint8_t ack = digitalRead(mDioPin);
151 
152  // Device releases DIO upon falling edge of the 9th CLK.
153  clockHigh();
154  clockLow();
155  return ack;
156  }
157 
158  void bitDelay() const { delayMicroseconds(mDelayMicros); }
159 
160  void clockHigh() const { pinMode(mClkPin, INPUT); bitDelay(); }
161 
162  void clockLow() const { pinMode(mClkPin, OUTPUT); bitDelay(); }
163 
164  void dataHigh() const { pinMode(mDioPin, INPUT); bitDelay(); }
165 
166  void dataLow() const { pinMode(mDioPin, OUTPUT); bitDelay(); }
167 
168  private:
169  uint8_t const mDioPin;
170  uint8_t const mClkPin;
171  uint8_t const mDelayMicros;
172 };
173 
174 } // ace_segment
175 
176 #endif
ace_segment::SoftTmiInterface::startCondition
void startCondition() const
Generate the I2C start condition.
Definition: SoftTmiInterface.h:106
ace_segment::SoftTmiInterface::begin
void begin() const
Initialize the dio and clk pins.
Definition: SoftTmiInterface.h:85
ace_segment::SoftTmiInterface::end
void end() const
Set dio and clk pins to INPUT mode.
Definition: SoftTmiInterface.h:100
ace_segment::SoftTmiInterface::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: SoftTmiInterface.h:127
ace_segment::SoftTmiInterface
Class that knows how to communicate with a TM1637 chip.
Definition: SoftTmiInterface.h:65
ace_segment::SoftTmiInterface::SoftTmiInterface
SoftTmiInterface(uint8_t dioPin, uint8_t clkPin, uint8_t delayMicros)
Constructor.
Definition: SoftTmiInterface.h:74
ace_segment::SoftTmiInterface::stopCondition
void stopCondition() const
Generate the I2C stop condition.
Definition: SoftTmiInterface.h:115