-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for reading from CD74HC165 shift-in register #408
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution!
I cannot merge this pull request here, the Arduino-Helpers code is maintained separately, so I would have to merge that upstream.
I've added some comments, but don't feel obligated to fix them, I have an old local shift register input class stashed somewhere that's still waiting for me to order some hardware to test it, so I could always push that.
@@ -17,6 +17,19 @@ | |||
"isDefault": true, | |||
}, | |||
}, | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tasks should use operating system specific options within a single task rather than having multiple tasks for different operating systems.
*/ | ||
void begin() override; | ||
|
||
void read(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function doesn't have a definition.
const pin_t clockEnablePin; | ||
const pin_t loadPin; | ||
|
||
uint8_t buffer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This buffer should have enough space to store N
bits, not just 8. It should probably be an AH::BitArray<N>
, like the ShiftRegisterOut
class.
|
||
template <uint8_t N> | ||
int ShiftRegisterIn<N>::digitalRead(pin_t pin) { | ||
return bitRead(buffer, pin); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bitRead
cannot address N
bits, this should be a read from the AH::BitArray<N>
.
|
||
template <uint8_t N> | ||
void ShiftRegisterIn<N>::pinMode(pin_t, PinMode_t mode) { | ||
ExtIO::pinMode(dataPin, mode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When do you have to change the mode of the data pin? AFAIK, shift registers have push/pull data outputs, so INPUT_PULLUP
should never be necessary. Even if INPUT_PULLUP
were necessary, it would have to be in a different method, the pinMode()
method should change the modes of the input of the IO extender, not the data pins.
|
||
// ISSUE: shiftIn is available when building for Arduino but not when | ||
// running tests | ||
buffer = shiftIn(dataPin, clockPin, LSBFIRST); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, this would use an ExtIO
version of shiftIn()
, similar to
Control-Surface/src/AH/Hardware/ExtendedInputOutput/ExtendedInputOutput.cpp
Lines 176 to 209 in a061a3a
void shiftOut(pin_t dataPin, pin_t clockPin, BitOrder_t bitOrder, uint8_t val) { | |
// Native version | |
if (isNativePin(dataPin) && isNativePin(clockPin)) { | |
::shiftOut((int)dataPin, (int)clockPin, bitOrder, val); | |
} | |
// ExtIO version | |
else if (!isNativePin(dataPin) && !isNativePin(clockPin)) { | |
auto dataEl = getIOElementOfPin(dataPin); | |
auto dataPinN = dataPin - dataEl->getStart(); | |
auto clockEl = getIOElementOfPin(clockPin); | |
auto clockPinN = clockPin - clockEl->getStart(); | |
for (uint8_t i = 0; i < 8; i++) { | |
uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i)); | |
dataEl->digitalWrite(dataPinN, (val & mask) ? HIGH : LOW); | |
clockEl->digitalWrite(clockPinN, HIGH); | |
clockEl->digitalWrite(clockPinN, LOW); | |
} | |
} | |
// Mixed version (slow) | |
else { | |
for (uint8_t i = 0; i < 8; i++) { | |
uint8_t mask = bitOrder == LSBFIRST ? (1 << i) : (1 << (7 - i)); | |
digitalWrite(dataPin, (val & mask) ? HIGH : LOW); | |
digitalWrite(clockPin, HIGH); | |
digitalWrite(clockPin, LOW); | |
} | |
} | |
} | |
void shiftOut(int dataPin, int clockPin, BitOrder_t bitOrder, uint8_t val) { | |
::shiftOut(arduino_pin_cast(dataPin), arduino_pin_cast(clockPin), bitOrder, | |
val); | |
} |
I'll see if I can add one.
I believe the bit order should be a parameter, similar to ShiftRegisterOut
.
} | ||
|
||
template <uint8_t N> | ||
void ShiftRegisterIn<N>::updateBufferedInputs() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the datasheet:
For predictable operation the LOW-to-HIGH transition of CE should only take place while CP is HIGH. Also, CP and CE should be LOW before the LOW-to-HIGH transition of PL to prevent shifting the data when PL goes HIGH.
I don't believe this is satisfied here.
This adds support for reading from the digital inputs on a CD74HC165 shift-in register. I based this on the multiplexer code and tested it in my own Arduino code. I'm on a Mac, so some of the build commands did not work and I added Mac equivalents to tasks.json. However, the arduino-example-builder exe does not run on Mac and I could not find a Mac equivalent.
the implementation uses
bitRead
andshiftIn
from the Arduino library and compiles fine, but when trying to add tests, these are not defined. should they be? or do we need our own implementation of these methods?as is, the test class is not useful - it's a placeholder. I'm happy to flesh it out when the missing Arduino methods are solved.