Shop OBEX P1 Docs P2 Docs Learn Events
Chipulater - Propeller Logic Emulator — Parallax Forums

Chipulater - Propeller Logic Emulator

Jorge PJorge P Posts: 385
edited 2015-04-20 15:10 in Robotics
I started this project in 2012 and though I lost all my files from a PC crash, I recently found a backup on DVD so I thought I would post this here for two reasons.

1.) So there is a backup online
2.) To share my project with the community

The code is documented as well as I could, and 1 bit of code, the flip flop, is incomplete. I will make modifications as needed. I hope you like the work so far :)

Rundown of the code:

* common Gates
* A Multiplexer ( 4 to 1 )
* A DeMultiplexer ( 1 to 4 )
* A Counter chip ( 4 bit )
* A Flip-Flop ( RS ) incomplete, need more info
{{

    Program_Name    : LOGIC.spin
    Program_Version : 1.0
    Program_Author  : Jorge Joaquin Pareja

    Copyright (c) Jorge Joaquin Pareja 2013-2015, all Rights Researved

    If you're like me and do not live around or near a store that supplies various
    computer chips, or you do not have the funding to purchase them, then you
    have limited resources.  This limitation can put your project on hold for
    quite some time, and maybe even indefinatly if you do not have funding.  So
    you just decide to pass your project idea by.

    Well, after reading some documentation and getting frustrated enough to
    say to myself, "I wish there was a way to get those chips I need faster".
    It ocured to me that I can use a propeller to emulate a multitude of varius
    IC's I could not get or that I could not find any more.

    This program is a sample of how to program the propeller to function as
    a general purpose IC that can emulate many types of gates, buffers, etc...
    hence the name of the program, CHIPULATOR, CHIP emULATOR.

    This also helps when learning how to use variouse chips and their function.
    Not to mention development costs, you can use a Propeller chip that we all
    usualy keep around to toy with.


    NOTE: voltage tolerances of all emulated IC's are that of the propeller.

        This project is not intended to replace a component, it is intended
        soley as a temporary workaround for missing parts you do not have in
        stock.


    This project is not intended to communicate serialy with any device,
    Propeller, or PC.  This is soley to allow a sense of piggy-backing
    using COGs.  Since each cog has access to all 32 pins, we can
    programaticaly piggy-back multiple gates to read the other gates and
    use the same inputs and use multiple outputs, or we can take the
    output of one and feed it back through to the others input.  All
    with nothing more than a few cogs.  Digital Feedback without passing
    variables to other cogs, Even though a pin is an output, you can still
    read its state with INA.

    This project uses the Propeller Proffessional Development Board (PPDB)
    The parts of the PPDB that I am using are the Buttons, Dipswitch, and
    LED's.  8 of each are required for the Full Project.

  *********************
    Project Goals
  *********************
    The PPDB has 16 LEDs, 1 - 8 Position Dip Switch, and 8 buttons that I
    will be using for the project.  The switches and buttons will serve as
    inputs to our gates and the LEDs will serve as a visual display of the
    output.  Although it may sound strange, we will be defining the
    hardware IC's completely in software.  Advanced users of the Propeller
    Chip will be able to add in more precice timing characteristics of the
    actual chips we will emulate by rewriting this project in assembler.

    This particular project will do it all in spin, without considering
    the un-emulated devices speed.  This is simply because I currently
    am not that proficient in PASM, I am learning though.

    This project will define a total of 7 gates, as well as gate
    configurations that will serve as the following.

        * A Multiplexer   ( 4 to 1 )
        * A DeMultiplexer ( 1 to 4 )
        * A Counter chip  ( 4 bit  )
        * A Flip-Flop     (   RS   ) incomplete

    If you do not understand the Logic of these circuits, you can toy
    with the logic using "Parallax Logic Simulator" as available on
    the "Parallax CD".  This Project is intended to match that same
    functionality and purpose.

    In software, I have expanded the inputs and outputs to be up to 8
    of each incase we want to have 2 or more seperate circuits defined
    with the propeller.  These inputs and outputs will be as follows:

        Pins  0.. 7  undefined
        Pins  8.. 15 INPUTS
        Pins 16.. 23 OUTPUTS
        Pins 24.. 32 undefined (with execption to progrming and startup pins 18,29,30,31)

     Leaving 16 pins for possible future expansion.  You will find that
     this is vary simple to program using spin.

     So enough smalltalk, lets get started.

}}
CON
    _CLKMODE = XTAL1 + PLL16X 'Standard clock mode * crystal frequency = 80 MHz
    _XINFREQ = 5_000_000

    ' the following constants currently are not used
    
    ' Signal Levels
    HIGH = 1
    LOW  = 0

    INVERTED_HIGH = 0
    INVERTED_LOW  = 1

    ' Gate types enum
    #0, NULL,     { turns GATE driver off and loops until command is set with new perameters
    }   _AND,     { configures driver as an 2 input AND  Gate
    }   _NAND,    { configures driver as an 2 input NAND Gate
    }   _NOT,     { configures driver as an 1 input NOT  Gate (also called an inverter)
    }   _OR,      { configures driver as an 2 input OR   Gate
    }   _XOR,     { configures driver as an 2 input XOR  Gate
    }   _NOR,     {
    }   _XNOR,    {
    }   _MUX,     {
    }   _DEMUX,   {
    }   _COUNTER, {
    }   _FLIPFLOP,{
    }   _BUFFER

    ' commands
    #0, cmdNULL,         { OK/READY 
    }   cmdStop,         { if a gate is running, this command stops it
    }   cmdSetGate,      {
    }   cmdInvertInput,  {
    }   cmdInvertOutput, {
    }   cmdSetInPins,    {
    }   cmdSetOutPin     {
    }

    ' return values
    #0, OK,        { Loaded and ready for commands
    }   READY,     { same as above
    }   BUSY,      { Commands have already ben sent, use cmdStop to stop the gate but not unload the cog
    }   ERROR,     { an unknown error occured
    }   STOPPED,   { occurs only after sending cmdStop, after reading this should be set to OK or READY
    }   NOT_LOADED,{ only set in spin, the cog has not been loaded
    }   ERR_NoGate { user forgot to set gate type prior to setting cmd
    }
{
VAR
    LONG  gateType
    LONG  inPin_A, inPin_B, inPin_C, inPin_D, inPin_E, inPin_F, inPin_G, inPin_H             ' input pins
    LONG  outPin_A, outPin_B, outPin_C, outPin_D, outPin_E, outPin_F, outPin_G, outPin_H     ' output pins
    LONG  gate_A, gate_B, gate_C, gate_D, gate_E, gate_F, gate_G, gate_H                     ' gate selection pins
    LONG  CE_0, CE_1, CE_2, CE_3, CE_4, CE_5, CE_6, CE_7                                     ' chip enable pins

OBJ
    'pst         : "Parallax Serial Terminal"
}
PUB Main
{{
    ''
    '' This is the code area that should be edited by the user
    '' to alter the function we wish to emulate.
    ''
}}
    DIRA[8..15]~                '' set pins 8 through 15 to inputs
    DIRA[16..23]~~              '' set pins 16 through 23 to outputs

    'GATE_NOT
    'GATE_BUFFER
    'GATE_AND
    'GATE_OR
    'GATE_NAND
    'GATE_NOR
    'GATE_XOR
    'GATE_XNOR

    'CHIP_MUX4
    'CHIP_DEMUX4
    'CHIP_COUNTER4
    CHIP_COUNTER8

PUB GATE_NOT
{{
  *********************
    The NOT Gate
  *********************
    The NOT gate, in my opinion, is the simplest of all the gates.  The
    output is NOT equal to the output.  So, when the input signal is
    high, the output signal will be low.  Likewise, when the input signal
    is low, the output will be high.

    The NOT gate is also called an INVERTER.  The input is inverted on
    the output.

        The truth table (LOGIC) of a NOT gate

        ┌────────┬────────┐
        │ INPUT  │ OUTPUT │
        ├────────┼────────┤
        │   0    │   1    │
        ├────────┼────────┤
        │   1    │   0    │
        └────────┴────────┘

    This can be defined in spin with very few lines of code.  4 to be exact!

        CODE:
                DIRA[8]~    ' set pin 8 to be input
                DIRA[23]~~  ' set pin 23 to be an output

                REPEAT
                  OUTA[23] := !INA[8] ' NOTE that when the button is NOT pressed
                                      ' the signal is HIGH on the PPDB.  This
                                      ' may lead to confusion by some new users,
                                      ' the gate is indeed functioning properly

    That is quite simple, but as noted, this project is designed for the PPDB
    and may be confusing to some who have not looked at the PPDB schmatic.

    Overall, that was quite simple.  I spent quite a bit of time searching
    electronics catalogs for various inverter chips and calculating costs.
    It was not until I wrote a single line of buggy spin code that I became
    aware that the software actualy defined this NOT gate.  The bug was
    exactly the NOTE that I wrote in the code itself about the Active Low
    push button circuit.

    The following pins should be wired to:
    
      P8 -> PB0   
      P23 -> LED_0

    --- Side Note: ---
        The first computer bug was on a punch-card reader.  A punch
        card is a piece of paper with holes punched into it to
        represent 1's and 0's, which is the binary representation of
        software.  The woman operating the machine noticed that
        there was some sort of problem with the program and removed
        the card to visualy inspect it, she noted in her log-book
        that she found a bug on the card, the bug she found was
        of the insect kind.

        I would assume that her notion to log the incident was to
        inform the other operators that insects can cause the
        machine to malfunction.  From that point on, all errors
        in programming have been called bugs, and she will
        forever be remembered for her discovery and coining the
        term.

    
}}
    REPEAT
      OUTA[23] := !INA[8]  ' NOTE that when the button is NOT pressed, the signal is HIGH on the PPDB
                           ' This may lead to confusion by some new users, the gate is indeed
                           ' functioning properly

PUB GATE_BUFFER
{{
  *********************
    The BUFFER
  *********************

    A buffer gate is the second easiest gate we can program. Similar to the NOT
    gate, it has one input and one output and requires the same amount of code
    minus one charactor.  The output will always equal the input. 

        CODE:
                DIRA[8]~    ' set pin 8 to be input
                DIRA[23]~~  ' set pin 23 to be an output

                REPEAT
                  OUTA[23] := INA[8]  ' NOTE that when the button is NOT pressed
                                      ' the input signal is HIGH on the PPDB.
                                      ' This may lead to confusion by some new
                                      ' users, the gate is indeed functioning
                                      ' properly

    If you compare the code, the line that reads "OUTA[23] := INA[8]" differs
    from that of the NOT gate.  The logic ! symbol in code stands for NOT.  Try
    not to get confused here and recall how the buttons are wired on the PPDB,
    they are active LOW so the code is correct for the PPDB hardware.

    If you think about it, A light switch on your wall is a buffer between you
    and the 110/220 volts of electricity from your power company.
}}
    REPEAT
      OUTA[23] := INA[8]  ' NOTE that when the button is NOT pressed
                          ' the input signal is HIGH on the PPDB.
                          ' This may lead to confusion by some new
                          ' users, the gate is indeed functioning
                          ' properly

PUB GATE_AND
{{
  *********************
    The AND Gate
  *********************

    An and gate uses atleast 2 inputs.  I will only be coding a 2 input AND gate
    so if your application requires more inputs, try expanding the code using
    the logic table of the AND gate you are emulating.

    This 2 input gate has 4 possible logical states:

        ┌────────┬────────┬┬────────┐
        │ INPUT  │ INPUT  ││ OUTPUT │
        │   A    │   B    ││        │
        ├────────┼────────┼┼────────┤
        ├────────┼────────┼┼────────┤
        │   0    │   0    ││   0    │
        ├────────┼────────┼┼────────┤
        │   0    │   1    ││   0    │
        ├────────┼────────┼┼────────┤
        │   1    │   0    ││   0    │
        ├────────┼────────┼┼────────┤
        │   1    │   1    ││   1    │
        └────────┴────────┴┴────────┘

    Only when both inputs are HIGH, the output will be HIGH.  You can also see
    that the input states are a binary representation of the numbers 0, 1, 2,
    and 3.  1/4 of a byte, 1/2 nibble.  The old term used in programming, which
    is rarely ever used, is called a TAYSTE or CRUMB.  Whereas the ouput is
    simply a BIT.
    
    In spin, the code to perform this type of function is as follows:

        CODE:
                REPEAT
                  IF INA[8] & INA[9]
                    OUTA[23]~~
                  ELSE
                    OUTA[23]~

    On the PPDB when a button 0 and/or 1 are pressed the LED goes off.  On
    other platforms with buttons wired active high, the LED will only iluminate
    when both buttons are pressed.
}}
    REPEAT
      IF INA[8] & INA[9]
        OUTA[23]~~
      ELSE
        OUTA[23]~

PUB GATE_OR
{{
  *********************
    The OR gate
  *********************
    The OR gate has 2 inputs and 1 output in the standard configuration.
    Allthough most of the gates throughout this tutorial have 2 inputs, they
    can contain many more.  The truth table for the 2 input OR gate is:

        ┌────────┬────────┬┬────────┐
        │ INPUT  │ INPUT  ││ OUTPUT │
        │   A    │   B    ││        │
        ├────────┼────────┼┼────────┤
        ├────────┼────────┼┼────────┤
        │   0    │   0    ││   0    │
        ├────────┼────────┼┼────────┤
        │   0    │   1    ││   1    │
        ├────────┼────────┼┼────────┤
        │   1    │   0    ││   1    │
        ├────────┼────────┼┼────────┤
        │   1    │   1    ││   1    │
        └────────┴────────┴┴────────┘

    if either or both inputs are HIGH the output is high.  Here is the code to
    perform this on the propeller:

        CODE:
                REPEAT
                  IF INA[8] | INA[9]
                    OUTA[23]~~
                  ELSE
                    OUTA[23]~

    You will notice that it looks nearly the same as the AND gate with the
    exception of one charactor.  Here, instead of & we use |.  This symbol
    is the "Vertical Bar" or "Pipe Symbol".
}}
    REPEAT
      IF INA[8] | INA[9]
        OUTA[23]~~
      ELSE
        OUTA[23]~

PUB GATE_NAND
{{
  *********************
    The NAND Gate
  *********************
    The NAND gate is a NOT-AND gate.  When either A, B, or Neither inputs are
    HIGH, the output is HIGH.  Only when both inputs are high does the gate
    turn off the output, here is the truth table for the NAND:

        ┌────────┬────────┬┬────────┐
        │ INPUT  │ INPUT  ││ OUTPUT │
        │   A    │   B    ││        │
        ├────────┼────────┼┼────────┤
        ├────────┼────────┼┼────────┤
        │   0    │   0    ││   1    │
        ├────────┼────────┼┼────────┤
        │   0    │   1    ││   1    │
        ├────────┼────────┼┼────────┤
        │   1    │   0    ││   1    │
        ├────────┼────────┼┼────────┤
        │   1    │   1    ││   0    │
        └────────┴────────┴┴────────┘

    The code is as follows:

        CODE:
                REPEAT
                  IF INA[8] & INA[9]
                    OUTA[23]~
                  ELSE
                    OUTA[23]~~

    Again, this looks like the AND gate code with the exception that both OUTA
    lines have been swapped in order to give the NAND gate effect.
}}
    REPEAT
      IF INA[8] & INA[9]
        OUTA[23]~
      ELSE
        OUTA[23]~~

PUB GATE_NOR
{{
  *********************
    The NOR Gate
  *********************
    The NOR gate is a NOT-OR gate.  The truth table is:

        ┌────────┬────────┬┬────────┐
        │ INPUT  │ INPUT  ││ OUTPUT │
        │   A    │   B    ││        │
        ├────────┼────────┼┼────────┤
        ├────────┼────────┼┼────────┤
        │   0    │   0    ││   1    │
        ├────────┼────────┼┼────────┤
        │   0    │   1    ││   0    │
        ├────────┼────────┼┼────────┤
        │   1    │   0    ││   0    │
        ├────────┼────────┼┼────────┤
        │   1    │   1    ││   0    │
        └────────┴────────┴┴────────┘

    If either or both inputs are HIGH, the output is LOW, otherwise the input
    is HIGH.

    The code is as follows:

        CODE:
                REPEAT
                  IF INA[8] | INA[9]
                    OUTA[23]~
                  ELSE
                    OUTA[23]~~
}}
    REPEAT
      IF INA[8] | INA[9]
        OUTA[23]~
      ELSE
        OUTA[23]~~

PUB GATE_XOR
{{
  *********************
    The XOR Gate
  *********************

    The Exclusive OR is a gate is one where when input A or B, but not both is
    HIGH, the output is HIGH.  If both or neither are HIGH, the output is LOW.
    The truth table is:

        ┌────────┬────────┬┬────────┐
        │ INPUT  │ INPUT  ││ OUTPUT │
        │   A    │   B    ││        │
        ├────────┼────────┼┼────────┤
        ├────────┼────────┼┼────────┤
        │   0    │   0    ││   0    │
        ├────────┼────────┼┼────────┤
        │   0    │   1    ││   1    │
        ├────────┼────────┼┼────────┤
        │   1    │   0    ││   1    │
        ├────────┼────────┼┼────────┤
        │   1    │   1    ││   0    │
        └────────┴────────┴┴────────┘

    Here is the code:

        CODE:
                REPEAT
                  IF INA[8] ^ INA[9]
                    OUTA[23]~~
                  ELSE
                    OUTA[23]~
}}
    REPEAT
      IF INA[8] ^ INA[9]
        OUTA[23]~~
      ELSE
        OUTA[23]~

PUB GATE_XNOR
{{
  *********************
    The XNOR Gate
  *********************

    The XNOR gate is an Exclusive NOT-OR gate, it is the opposit of the XOR
    gate ain that when neither or both inputs are HIGH, the output is HIGH.

    The truth table:
    
        ┌────────┬────────┬┬────────┐
        │ INPUT  │ INPUT  ││ OUTPUT │
        │   A    │   B    ││        │
        ├────────┼────────┼┼────────┤
        ├────────┼────────┼┼────────┤
        │   0    │   0    ││   1    │
        ├────────┼────────┼┼────────┤
        │   0    │   1    ││   0    │
        ├────────┼────────┼┼────────┤
        │   1    │   0    ││   0    │
        ├────────┼────────┼┼────────┤
        │   1    │   1    ││   1    │
        └────────┴────────┴┴────────┘

    and the code:

                REPEAT
                  IF INA[8] ^ INA[9]
                    OUTA[23]~
                  ELSE
                    OUTA[23]~~
}}
    REPEAT
      IF INA[8] ^ INA[9]
        OUTA[23]~
      ELSE
        OUTA[23]~~

PUB CHIP_MUX4
{{
  *********************
    The MUX chip
  *********************

    A MUX is a set of variouse gates used in combination.  The Multiplexer as
    depicted in the Parallax Logic Simulator can be emulated with:

        * 4 - AND Gates
        * 2 - OR gates
        * 2 - One line to two line decoders

    Rather than constructing the circuit, we will do this in code since it
    would take up 24 pins if we used each gate seperatly.  The BITWISE and
    BOOLEAN Operators of Spin are all that is required here, we will then
    be able to simply use a total of 8 I/O pins.  That sure beats 24 pins.

    The pins on the left will serve as the 7 inputs wile the right side
    will serve as the outputs for the remainder of these lessons.

    For the Multiplexer the following pins are defined:

        P8  = X0
        P9  = X1
        P10 = X2
        P11 = X4

        P12 = A
        P13 = B

        P14 = EN note this pin will be inverted

        P16 = X this is the only output

    Now lets take a look at the Truth table:

        ┌────────┬────────┬────────┬┬────────┐
        │        │        │        ││ OUTPUT │
        │ Enable │   B    │   A    ││  P16 = │
        ├────────┼────────┼────────┼┼────────┤
        ├────────┼────────┼────────┼┼────────┤
        │   1    │   -    │   -    ││ None   │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   0    │   0    ││  X0    │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   0    │   1    ││  X1    │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   1    │   0    ││  X2    │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   1    │   1    ││  X3    │
        └────────┴────────┴────────┴┴────────┘

    I should note here that the Enable line should be tied HIGH through a 10K
    resistor for this emulator, we then will only need to drive it low.  On
    the PPDB this is taken care of on the push button we will be using.  I will
    now need to describe the tie points for this more advanced emulation on
    the PPDB:

        DS_7 to  P8, X0
        DS_6 to  P9, X1
        DS_5 to P10, X2
        DS_4 to P11, X3

        DS_1 to P12, A
        DS_0 to P13, B

        PB_0 to P14, EN

        LED0 to P16

    A reminder here, if you look at the button and dipswitch schematic of the
    PPDB you will see that they are all tied high through a 10k resistor.  So
    the dip switches should all be in the ON position, all UP.

    Now for some code!  I will start out with the enable button.  The EN pin
    is active low, button 0 pressed, and our code should only process the other
    pins when this pin is LOW.  This should give us time enough to set the
    dipswitch to the settings we want without inadvertantly executing code:

        CODE:

              REPEAT
                IF INA[14] == 0   
                  IF INA[12] == 0 AND INA[13] == 0
                    OUTA[16] := INA[8]
                  IF INA[12] == 1 AND INA[13] == 0
                    OUTA[16] := INA[9]
                  IF INA[12] == 0 AND INA[13] == 1
                    OUTA[16] := INA[10]
                  IF INA[12] == 1 AND INA[13] == 1
                    OUTA[16] := INA[11]
                ELSE
                  OUTA[16]~

    as long as everything is wired properly, it works like a charm.  Pretty
    neat, eh?  It was actualy much simpler that I imagined it would be.
}}
    REPEAT
      IF INA[14] == 0   
        IF INA[12] == 0 AND INA[13] == 0
          OUTA[16] := INA[8]
        IF INA[12] == 1 AND INA[13] == 0
          OUTA[16] := INA[9]
        IF INA[12] == 0 AND INA[13] == 1
          OUTA[16] := INA[10]
        IF INA[12] == 1 AND INA[13] == 1
          OUTA[16] := INA[11]
      ELSE
        OUTA[16]~

PUB CHIP_DEMUX4
{{
  *********************
    The DEMUX chip
  *********************

    The Demultiplexer is the oposit of the Multiplexer in that it has four
    outputs and one input, not including the A, B and EN signals.  The
    demultiplexer may seem pointless, at first sight, due to the fact that
    it requires 4 inputs to setup its four outputs.  If you have enough pins
    you can just connect the microcontroller to what would be connected to the
    X# signals.  However, if you have a design you wish to expand and have less
    than four pins left over, but are using other chips with a CE or EN signal,
    we can most likely squeeze in a demultiplexer.  Here is the truth table:

        ┌────────┬────────┬────────┬┬────────┐
        │        │        │        ││ INPUT  │
        │ Enable │   B    │   A    ││  X to  │
        ├────────┼────────┼────────┼┼────────┤
        ├────────┼────────┼────────┼┼────────┤
        │   1    │   -    │   -    ││ None   │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   0    │   0    ││  X0    │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   0    │   1    ││  X1    │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   1    │   0    ││  X2    │
        ├────────┼────────┼────────┼┼────────┤
        │   0    │   1    │   1    ││  X3    │
        └────────┴────────┴────────┴┴────────┘

    Lets assume the following scenario:

        You have 29 of your propeller pins used up with other circuitry.
        In that circuitry you have used the following:

            * DS1302
            * L293D
            * various other imaginary circuits

        as long as we know when the DS1302 and L293D chip are being used we
        can simply use one of the free pins for the multiplexer CHIP. How you
        ask?  Well as long as the other chips respective EN and CE lines are
        not in their ACTIVE state we can use any of their other signal lines
        giving us access to up to 6 data lines when we thought we only had two.

        Technicaly we have a total of 8 pins we can use AS LONG AS we do not
        enable the other chips while communicating.

        With that in mind, lets assume our pins are as follows, or something
        similar:

                DS3102
                  SCLK   to  P8
                  I/O    to  P9
                  
                  CE     to  P0
                 
                L293D
                  EN 0,1 to  P1
                  EN 2,3 to  P2
                 
                  Input0 to  P8
                  Input1 to  P9
                  Input2 to P10
                  Input3 to P11
                 
                A Real MULTIPLEXER chip
                  EN     to  P3
                 
                  A      to  P8
                  B      to  P9
                 
                  X      to P10

    You would then be able to do some fancy coding to work it all out while
    making sure you do not Clobber a signal.  It would take alot of care to
    do all this.  Thats what the demultiplexer is designed for.  That was just
    a scenario to consider why to use the DEMUX, lets get onto the emulation of
    it.

    We don't need to ripup the previous lesson, the multiplexor, we can leave
    it in place and use a second button and the same IO pins as the multiplexr.

      PB1 to  P15

      LED0 to P16
      LED1 to P17
      LED2 to P18
      LED3 to P19

    The following connections should already be in place unless you ripped it up
    after the last lesson.
    
      DS7  to  P8     Now X for this Emulation

      DS_1 to P12, A
      DS_0 to P13, B

    With everything in place, lets code the following:

        CODE:

              REPEAT
                IF INA[15] == 0   
                  IF INA[12] == 0 AND INA[13] == 0
                    OUTA[16] := INA[8]
                  IF INA[12] == 1 AND INA[13] == 0
                    OUTA[16] := INA[9]
                  IF INA[12] == 0 AND INA[13] == 1
                    OUTA[16] := INA[10]
                  IF INA[12] == 1 AND INA[13] == 1
                    OUTA[16] := INA[11]
                ELSE
                  OUTA[16]~

    Nice, it works like a charm.  Again, if you have any problems double
    check your wiring and make sure the switches, buttons, and LEDs are wired
    to mimic the PPDB.
}}
    REPEAT
      IF INA[15] == 0
        IF INA[12] == 0 AND INA[13] == 0
          OUTA[16] := INA[8]
        IF INA[12] == 1 AND INA[13] == 0
          OUTA[17] := INA[8]
        IF INA[12] == 0 AND INA[13] == 1
          OUTA[18] := INA[8]
        IF INA[12] == 1 AND INA[13] == 1
          OUTA[19] := INA[8]

      ELSE
        OUTA[16..19]~

PUB CHIP_COUNTER4 | tmp
{{
  *********************
    The COUNTER chip
  *********************

    I have never used a counter, I would assume they are used in devices like
    change counters and vending machines to count coins and such.  I would
    imagine that a digital micrometer would have one as well, wired up to
    a hall effect sensor of some sort.

    If a counter has enough outputs, we could see the output of devices like
    the PING using an aceleromiters motion sensing abilities to the reset.

    We do not need to rewwire anything from the demultipler emulator circuit,
    but if you ripped it up here is the wiring:

        LED0 to P16, Q1
        LED1 to P17, Q2
        LED2 to P18, Q3
        LED3 to P19, Q4

        DS0  to P14, R
        PB0  to P13, CLK  active low

    we will need a variable to hold our count so far, here is the code

        CODE

                tmp := 0
    
                REPEAT
                  IF INA[14] == 1    ' R
                    tmp := 0
                    OUTA[19..16] := 0
                  ELSE
                    IF INA[13] == 0  ' CLK
                      tmp += 1
                      IF tmp == 16
                        tmp := 0
                      REPEAT UNTIL (INA[14] == 1) or (INA[13] == 1)
                        OUTA[19..16] := tmp
        

    There we have it, a counter chip emulated on the propeller, don't forget
    that the propeller has a set of 2 counters per COG for a total of 16.  If
    you need, you can use that instead to incriment the data.  I have not, yet,
    gotten arround to using them in my own code.
}}
    tmp := 0
    
    REPEAT
      IF INA[14] == 1    ' R
        tmp := 0
        OUTA[19..16] := 0
      ELSE
        IF INA[13] == 0  ' CLK
          tmp += 1
          IF tmp == 16
            tmp := 0
          REPEAT UNTIL (INA[14] == 1) or (INA[13] == 1)
            OUTA[19..16] := tmp

PUB CHIP_COUNTER8 | tmp
{{
    CHIP_COUNTER4 is expanded with 4 more outputs for a total of 8

    P16..23 are outputs wired to LEDs 0..7
    P13 is input and connects to button 0, the clock
    P14 is input and connected to dipswitch 0.  Off resets, ON keeps count.
}}
    REPEAT
      IF INA[14] == 1    ' R
        tmp := 0
        OUTA[23..16] := 0
      ELSE
        IF INA[13] == 0  ' CLK
          tmp += 1
          IF tmp == 256
            tmp := 0
          REPEAT UNTIL (INA[14] == 1) or (INA[13] == 1)
            OUTA[23..16] := tmp

PUB CHIP_FLIPFLOP_RS | set, reset, clock, data, q, qi
{{
    *********************
      the FLIPFLOP (RS Type)
    *********************

    RS FlipFlop is an edge triggerd device.

    (INCOMPLETE)
  
}}

    ' setup propeller pins
    SET   := 15  ' falling edge
    CLOCK := 14  ' rising edge
    DATA  := 13  ' 
    RESET := 12  ' falling edge

    Q     := 17
    QI    := 16

    ' setup directions
    DIRA[RESET..SET]~   ' inputs
    DIRA[Q..QI]~~       ' outputs

    ' functional code

        

I hope to get some feedback on what I can improve, and possibly some timings on the gates as read by a scope, I do not have one, and how the code compares to actual logic IC's. I have a few more bits of code but will wait to post it all until I go over it again, its been missing for 2 years. So glad I found my old project.

Comment if you like the code/idea :)

Comments

Sign In or Register to comment.