work in progress

Dependencies:   FastAnalogIn FastIO USBDevice mbed FastPWM SimpleDMA

Fork of Pinscape_Controller by Mike R

Committer:
mkalkbrenner
Date:
Wed Dec 16 15:37:59 2015 +0000
Revision:
38:697e10d8fb80
Parent:
36:6b981a2afab7
fixed default configuration for extension boards

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 36:6b981a2afab7 1 /* Copyright 2014 M J Roberts, MIT License
mjr 36:6b981a2afab7 2 *
mjr 36:6b981a2afab7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
mjr 36:6b981a2afab7 4 * and associated documentation files (the "Software"), to deal in the Software without
mjr 36:6b981a2afab7 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
mjr 36:6b981a2afab7 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
mjr 36:6b981a2afab7 7 * Software is furnished to do so, subject to the following conditions:
mjr 36:6b981a2afab7 8 *
mjr 36:6b981a2afab7 9 * The above copyright notice and this permission notice shall be included in all copies or
mjr 36:6b981a2afab7 10 * substantial portions of the Software.
mjr 36:6b981a2afab7 11 *
mjr 36:6b981a2afab7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
mjr 36:6b981a2afab7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
mjr 36:6b981a2afab7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
mjr 36:6b981a2afab7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mjr 36:6b981a2afab7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mjr 36:6b981a2afab7 17 */
mjr 36:6b981a2afab7 18
mjr 36:6b981a2afab7 19 #ifndef HC595_INCLUDED
mjr 36:6b981a2afab7 20 #define HC595_INCLUDED
mjr 36:6b981a2afab7 21
mjr 36:6b981a2afab7 22 #include "mbed.h"
mjr 36:6b981a2afab7 23
mjr 36:6b981a2afab7 24 // 74HC595 Interface
mjr 36:6b981a2afab7 25 //
mjr 36:6b981a2afab7 26 // We require four GPIO pins:
mjr 36:6b981a2afab7 27 //
mjr 36:6b981a2afab7 28 // sin - serial data
mjr 36:6b981a2afab7 29 // sclk - serial clock
mjr 36:6b981a2afab7 30 // latch - the LATCH signal, which transfers the internal shift register
mjr 36:6b981a2afab7 31 // bits to the physical output pin states
mjr 36:6b981a2afab7 32 // ena - the Enable signal
mjr 36:6b981a2afab7 33 //
mjr 36:6b981a2afab7 34 // Note that the physical !OE (output enable) pin on the 74HC595 is active-low.
mjr 36:6b981a2afab7 35 // To allow for orderly startup that guarantees that outputs won't be pulsed
mjr 36:6b981a2afab7 36 // (even briefly) during power-on, we require the !OE pin to be wired with a
mjr 36:6b981a2afab7 37 // pull-up resistor to Vcc, and connected to our ENA GPIO pin via an inverter.
mjr 36:6b981a2afab7 38 //
mjr 36:6b981a2afab7 39 // Recommended wiring: connect the GPIO pin to the base of an NPN transistor
mjr 36:6b981a2afab7 40 // through a 2.2K resistor, connect the collector the !OE pin on the 74HC595,
mjr 36:6b981a2afab7 41 // and connect the emitter to ground. This will pull !OE to ground when we
mjr 36:6b981a2afab7 42 // write a digital 1 to the ENA GPIO, enabling the outputs.
mjr 36:6b981a2afab7 43 //
mjr 36:6b981a2afab7 44 // We use simple bit-banging through plain DigitalOut pins to send serial
mjr 36:6b981a2afab7 45 // data to the chips. This is fast enough for our purposes, since we send
mjr 36:6b981a2afab7 46 // only 8 bits per chip on each update (about 4us per chip per update), and
mjr 36:6b981a2afab7 47 // we only update when we get a command from the PC host that changes an
mjr 36:6b981a2afab7 48 // output state. These updates are at USB speed, so the update interval is
mjr 36:6b981a2afab7 49 // extremely long compared to the bit-banging time. If we wanted to use
mjr 36:6b981a2afab7 50 // these chips to implement PWM controlled by the microcontroller, or we
mjr 36:6b981a2afab7 51 // simply wanted to use a very long daisy-chain, we'd probably have to use
mjr 36:6b981a2afab7 52 // a faster transfer mechanism, such as the SPIO controller.
mjr 36:6b981a2afab7 53
mjr 36:6b981a2afab7 54 class HC595
mjr 36:6b981a2afab7 55 {
mjr 36:6b981a2afab7 56 public:
mjr 36:6b981a2afab7 57 HC595(int nchips, PinName sin, PinName sclk, PinName latch, PinName ena) :
mjr 36:6b981a2afab7 58 nchips(nchips), sin(sin), sclk(sclk), latch(latch), ena(ena)
mjr 36:6b981a2afab7 59 {
mjr 36:6b981a2afab7 60 // turn off all pins initially
mjr 36:6b981a2afab7 61 this->sin = 0;
mjr 36:6b981a2afab7 62 this->sclk = 0;
mjr 36:6b981a2afab7 63 this->latch = 0;
mjr 36:6b981a2afab7 64 this->ena = 0;
mjr 36:6b981a2afab7 65
mjr 36:6b981a2afab7 66 // allocate the state array
mjr 36:6b981a2afab7 67 state = new char[nchips*8];
mjr 36:6b981a2afab7 68 memset(state, 0, nchips*8);
mjr 36:6b981a2afab7 69 dirty = false;
mjr 36:6b981a2afab7 70 }
mjr 36:6b981a2afab7 71
mjr 36:6b981a2afab7 72 // Initialize. This must be called once at startup to clear the chips'
mjr 36:6b981a2afab7 73 // shift registers and enable the physical outputs. We clock a 0 bit (OFF
mjr 36:6b981a2afab7 74 // state) to each shift register position, latch the OFF states on the
mjr 36:6b981a2afab7 75 // outputs, and enable the chips.
mjr 36:6b981a2afab7 76 void init()
mjr 36:6b981a2afab7 77 {
mjr 36:6b981a2afab7 78 // set the internal state of all inputs
mjr 36:6b981a2afab7 79 memset(state, 0, nchips*8);
mjr 36:6b981a2afab7 80 dirty = false;
mjr 36:6b981a2afab7 81
mjr 36:6b981a2afab7 82 // clock a 0 to each shift register bit (8 per chip)
mjr 36:6b981a2afab7 83 sin = 0;
mjr 36:6b981a2afab7 84 for (int i = 0 ; i < nchips*8 ; ++i)
mjr 36:6b981a2afab7 85 {
mjr 36:6b981a2afab7 86 sclk = 1;
mjr 36:6b981a2afab7 87 sclk = 0;
mjr 36:6b981a2afab7 88 }
mjr 36:6b981a2afab7 89
mjr 36:6b981a2afab7 90 // latch the output data (this transfers the serial data register
mjr 36:6b981a2afab7 91 // bit for each pin to the actual output pin)
mjr 36:6b981a2afab7 92 latch = 1;
mjr 36:6b981a2afab7 93 latch = 0;
mjr 36:6b981a2afab7 94
mjr 36:6b981a2afab7 95 // enable the outputs
mjr 36:6b981a2afab7 96 ena = 1;
mjr 36:6b981a2afab7 97 }
mjr 36:6b981a2afab7 98
mjr 36:6b981a2afab7 99 // Set an output state. This only sets the state internally; call
mjr 36:6b981a2afab7 100 // update() to apply changes to the physical outputs.
mjr 36:6b981a2afab7 101 void set(int idx, int val)
mjr 36:6b981a2afab7 102 {
mjr 36:6b981a2afab7 103 if (state[idx] != val)
mjr 36:6b981a2afab7 104 {
mjr 36:6b981a2afab7 105 state[idx] = val;
mjr 36:6b981a2afab7 106 dirty = true;
mjr 36:6b981a2afab7 107 }
mjr 36:6b981a2afab7 108 }
mjr 36:6b981a2afab7 109
mjr 36:6b981a2afab7 110 // Apply updates. This sends the current state of each pin to the
mjr 36:6b981a2afab7 111 // chips and latches the new settings.
mjr 36:6b981a2afab7 112 void update()
mjr 36:6b981a2afab7 113 {
mjr 36:6b981a2afab7 114 // if we have changes to apply, send the changes
mjr 36:6b981a2afab7 115 if (dirty)
mjr 36:6b981a2afab7 116 {
mjr 36:6b981a2afab7 117 // Clock out the new states. Since the outputs are arranged
mjr 36:6b981a2afab7 118 // as shift registers, we have to clock out the bits in reverse
mjr 36:6b981a2afab7 119 // order of port numbers - the first bit we output will end up
mjr 36:6b981a2afab7 120 // in the last register after we clock out all of the other bits.
mjr 36:6b981a2afab7 121 // So clock out the last bit first and the first bit last.
mjr 36:6b981a2afab7 122 for (int i = nchips*8-1 ; i >= 0 ; --i)
mjr 36:6b981a2afab7 123 {
mjr 36:6b981a2afab7 124 sclk = 0;
mjr 36:6b981a2afab7 125 sin = state[i];
mjr 36:6b981a2afab7 126 sclk = 1;
mjr 36:6b981a2afab7 127 }
mjr 36:6b981a2afab7 128
mjr 36:6b981a2afab7 129 // latch the new states
mjr 36:6b981a2afab7 130 latch = 1;
mjr 36:6b981a2afab7 131 sclk = 0;
mjr 36:6b981a2afab7 132 latch = 0;
mjr 36:6b981a2afab7 133
mjr 36:6b981a2afab7 134 // outputs now reflect internal state
mjr 36:6b981a2afab7 135 dirty = false;
mjr 36:6b981a2afab7 136 }
mjr 36:6b981a2afab7 137 }
mjr 36:6b981a2afab7 138
mjr 36:6b981a2afab7 139
mjr 36:6b981a2afab7 140 private:
mjr 36:6b981a2afab7 141 int nchips; // number of chips in daisy chain
mjr 36:6b981a2afab7 142 bool dirty; // do we have changes to send to the chips?
mjr 36:6b981a2afab7 143 DigitalOut sin; // serial data pin
mjr 36:6b981a2afab7 144 DigitalOut sclk; // serial clock pin
mjr 36:6b981a2afab7 145 DigitalOut latch; // latch pin
mjr 36:6b981a2afab7 146 DigitalOut ena; // enable pin
mjr 36:6b981a2afab7 147 char *state; // array of current output states (0=off, 1=on)
mjr 36:6b981a2afab7 148 };
mjr 36:6b981a2afab7 149
mjr 36:6b981a2afab7 150 #endif // HC595_INCLUDED