Line data Source code
1 : // --------------------------------------------------------------------------- 2 : // USB EPROM/Flash Programmer 3 : // 4 : // Copyright (2022) Robson Martins 5 : // 6 : // This work is licensed under a Creative Commons Attribution-NonCommercial- 7 : // ShareAlike 4.0 International License. 8 : // --------------------------------------------------------------------------- 9 : /** 10 : * @ingroup Firmware 11 : * @file circuits/74hc165.cpp 12 : * @brief Implementation of the 74HC165 Class. 13 : * 14 : * @author Robson Martins (https://www.robsonmartins.com) 15 : */ 16 : // --------------------------------------------------------------------------- 17 : 18 : #include "circuits/74hc165.hpp" 19 : 20 : // --------------------------------------------------------------------------- 21 : 22 39 : HC165::HC165() : ce_(false) { 23 39 : configure(); 24 39 : } 25 : 26 1 : HC165::HC165(uint plPin, uint clkPin, uint cePin, uint q7Pin, uint nq7Pin, 27 1 : uint pulseTime) 28 1 : : ce_(false) { 29 1 : configure(plPin, clkPin, cePin, q7Pin, nq7Pin, pulseTime); 30 1 : } 31 : 32 45 : void HC165::configure(uint plPin, uint clkPin, uint cePin, uint q7Pin, 33 : uint nq7Pin, uint pulseTime) { 34 45 : plPin_ = plPin; 35 45 : clkPin_ = clkPin; 36 45 : cePin_ = cePin; 37 45 : q7Pin_ = q7Pin; 38 45 : nq7Pin_ = nq7Pin; 39 45 : pulseTime_ = pulseTime; 40 45 : } 41 : 42 3 : void HC165::chipEnable(bool value) { 43 3 : if (cePin_ != 0xFF) { 44 3 : gpio_.setPin(cePin_, !value); 45 : } 46 3 : ce_ = value; 47 3 : } 48 : 49 1 : void HC165::chipDisable(void) { 50 1 : if (cePin_ != 0xFF) { 51 1 : gpio_.setPin(cePin_); 52 : } 53 1 : ce_ = false; 54 1 : } 55 : 56 5 : const bool HC165::getCE(void) const { 57 5 : return ce_; 58 : } 59 : 60 3 : void HC165::load() { 61 3 : if (plPin_ != 0xFF) { 62 2 : gpio_.resetPin(plPin_); 63 2 : sleep_us(pulseTime_); 64 2 : gpio_.setPin(plPin_); 65 : } 66 3 : } 67 : 68 9 : bool HC165::getBit(uint index) { 69 9 : if (clkPin_ == 0xFF || (q7Pin_ == 0xFF && nq7Pin_ == 0xFF)) { 70 1 : return false; 71 : } 72 52 : for (uint i = 0; i < index; i++) { 73 44 : gpio_.setPin(clkPin_); 74 44 : sleep_us(pulseTime_); 75 44 : gpio_.resetPin(clkPin_); 76 44 : sleep_us(pulseTime_); 77 : } 78 8 : if (q7Pin_ != 0xFF) { 79 7 : return (gpio_.getPin(q7Pin_)); 80 : } else { 81 1 : return (!gpio_.getPin(nq7Pin_)); 82 : } 83 : } 84 : 85 5 : uint8_t HC165::readByte(bool reverse) { 86 5 : uint8_t buffer = 0; 87 5 : if (readData(&buffer, 1, reverse) != 1) { 88 1 : return 0; 89 : } 90 4 : return buffer; 91 : } 92 : 93 4 : uint16_t HC165::readWord(bool reverse) { 94 : uint8_t buffer[2]; 95 4 : if (readData(buffer, 2, reverse) != 2) { 96 1 : return 0; 97 : } 98 3 : uint16_t result = buffer[1]; 99 3 : result <<= 8; 100 3 : result |= buffer[0]; 101 3 : return result; 102 : } 103 : 104 4 : uint32_t HC165::readDWord(bool reverse) { 105 : uint8_t buffer[4]; 106 4 : if (readData(buffer, 4, reverse) != 4) { 107 1 : return 0; 108 : } 109 3 : uint32_t result = buffer[3]; 110 3 : result <<= 8; 111 3 : result |= buffer[2]; 112 3 : result <<= 8; 113 3 : result |= buffer[1]; 114 3 : result <<= 8; 115 3 : result |= buffer[0]; 116 3 : return result; 117 : } 118 : 119 14 : uint HC165::readData(uint8_t* buffer, uint size, bool reverse) { 120 14 : if (!buffer || !size) { 121 0 : return 0; 122 : } 123 14 : if (clkPin_ == 0xFF || (q7Pin_ == 0xFF && nq7Pin_ == 0xFF)) { 124 3 : return 0; 125 : } 126 11 : TData bits; 127 251 : for (uint i = 0; i < size * 8; i++) { 128 240 : if (q7Pin_ != 0xFF) { 129 232 : bits.push_back(gpio_.getPin(q7Pin_)); 130 : } else { 131 8 : bits.push_back(!gpio_.getPin(nq7Pin_)); 132 : } 133 240 : gpio_.setPin(clkPin_); 134 240 : sleep_us(pulseTime_); 135 240 : gpio_.resetPin(clkPin_); 136 240 : sleep_us(pulseTime_); 137 : } 138 11 : std::size_t start = reverse ? 0 : bits.size() - 1; 139 11 : std::size_t end = reverse ? bits.size() - 1 : 0; 140 11 : std::size_t nbit = start; 141 30 : for (uint nbyte = 0; nbyte < size; nbyte++) { 142 30 : buffer[nbyte] = 0; 143 259 : for (uint b = 0; b < 8; b++) { 144 240 : if (bits[nbit]) { 145 120 : buffer[nbyte] |= (1 << b); 146 : } 147 240 : if (nbit == end) { 148 11 : break; 149 : } 150 229 : if (reverse) { 151 53 : nbit++; 152 : } else { 153 176 : nbit--; 154 : } 155 : } 156 30 : if (nbit == end) { 157 11 : break; 158 : } 159 : } 160 11 : return size; 161 11 : }