Pinscape Controller version 1 fork. This is a fork to allow for ongoing bug fixes to the original controller version, from before the major changes for the expansion board project.
Dependencies: FastIO FastPWM SimpleDMA mbed
Fork of Pinscape_Controller by
74HC595.h
00001 /* Copyright 2014 M J Roberts, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #ifndef HC595_INCLUDED 00020 #define HC595_INCLUDED 00021 00022 #include "mbed.h" 00023 00024 // 74HC595 Interface 00025 // 00026 // We require four GPIO pins: 00027 // 00028 // sin - serial data 00029 // sclk - serial clock 00030 // latch - the LATCH signal, which transfers the internal shift register 00031 // bits to the physical output pin states 00032 // ena - the Enable signal 00033 // 00034 // Note that the physical !OE (output enable) pin on the 74HC595 is active-low. 00035 // To allow for orderly startup that guarantees that outputs won't be pulsed 00036 // (even briefly) during power-on, we require the !OE pin to be wired with a 00037 // pull-up resistor to Vcc, and connected to our ENA GPIO pin via an inverter. 00038 // 00039 // Recommended wiring: connect the GPIO pin to the base of an NPN transistor 00040 // through a 2.2K resistor, connect the collector the !OE pin on the 74HC595, 00041 // and connect the emitter to ground. This will pull !OE to ground when we 00042 // write a digital 1 to the ENA GPIO, enabling the outputs. 00043 // 00044 // We use simple bit-banging through plain DigitalOut pins to send serial 00045 // data to the chips. This is fast enough for our purposes, since we send 00046 // only 8 bits per chip on each update (about 4us per chip per update), and 00047 // we only update when we get a command from the PC host that changes an 00048 // output state. These updates are at USB speed, so the update interval is 00049 // extremely long compared to the bit-banging time. If we wanted to use 00050 // these chips to implement PWM controlled by the microcontroller, or we 00051 // simply wanted to use a very long daisy-chain, we'd probably have to use 00052 // a faster transfer mechanism, such as the SPIO controller. 00053 00054 class HC595 00055 { 00056 public: 00057 HC595(int nchips, PinName sin, PinName sclk, PinName latch, PinName ena) : 00058 nchips(nchips), sin(sin), sclk(sclk), latch(latch), ena(ena) 00059 { 00060 // turn off all pins initially 00061 this->sin = 0; 00062 this->sclk = 0; 00063 this->latch = 0; 00064 this->ena = 0; 00065 00066 // allocate the state array 00067 state = new char[nchips*8]; 00068 memset(state, 0, nchips*8); 00069 dirty = false; 00070 } 00071 00072 // Initialize. This must be called once at startup to clear the chips' 00073 // shift registers and enable the physical outputs. We clock a 0 bit (OFF 00074 // state) to each shift register position, latch the OFF states on the 00075 // outputs, and enable the chips. 00076 void init() 00077 { 00078 // set the internal state of all inputs 00079 memset(state, 0, nchips*8); 00080 dirty = false; 00081 00082 // clock a 0 to each shift register bit (8 per chip) 00083 sin = 0; 00084 for (int i = 0 ; i < nchips*8 ; ++i) 00085 { 00086 sclk = 1; 00087 sclk = 0; 00088 } 00089 00090 // latch the output data (this transfers the serial data register 00091 // bit for each pin to the actual output pin) 00092 latch = 1; 00093 latch = 0; 00094 00095 // enable the outputs 00096 ena = 1; 00097 } 00098 00099 // Set an output state. This only sets the state internally; call 00100 // update() to apply changes to the physical outputs. 00101 void set(int idx, int val) 00102 { 00103 if (state[idx] != val) 00104 { 00105 state[idx] = val; 00106 dirty = true; 00107 } 00108 } 00109 00110 // Apply updates. This sends the current state of each pin to the 00111 // chips and latches the new settings. 00112 void update() 00113 { 00114 // if we have changes to apply, send the changes 00115 if (dirty) 00116 { 00117 // Clock out the new states. Since the outputs are arranged 00118 // as shift registers, we have to clock out the bits in reverse 00119 // order of port numbers - the first bit we output will end up 00120 // in the last register after we clock out all of the other bits. 00121 // So clock out the last bit first and the first bit last. 00122 for (int i = nchips*8-1 ; i >= 0 ; --i) 00123 { 00124 sclk = 0; 00125 sin = state[i]; 00126 sclk = 1; 00127 } 00128 00129 // latch the new states 00130 latch = 1; 00131 sclk = 0; 00132 latch = 0; 00133 00134 // outputs now reflect internal state 00135 dirty = false; 00136 } 00137 } 00138 00139 00140 private: 00141 int nchips; // number of chips in daisy chain 00142 bool dirty; // do we have changes to send to the chips? 00143 DigitalOut sin; // serial data pin 00144 DigitalOut sclk; // serial clock pin 00145 DigitalOut latch; // latch pin 00146 DigitalOut ena; // enable pin 00147 char *state; // array of current output states (0=off, 1=on) 00148 }; 00149 00150 #endif // HC595_INCLUDED
Generated on Wed Jul 13 2022 23:56:13 by 1.7.2