Shop Learn
Propeller Assembly for beginners - Page 8 — Parallax Forums

Propeller Assembly for beginners

1568101129

Comments

  • StefanL38StefanL38 Posts: 2,290
    edited 2011-08-03 23:33
    @kuroneko:

    as the code is written now it needs a label for the call of the delay_"subroutine" the label named "Init_delaying"
    and a label where to jump while decrementing the label named "delay_loop"
    obviously djnz delay_counter, #Init_delaying would create an inifinite loop that would wait endles

    keep the questions coming
    best regards

    Stefan
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-03 23:40
    StefanL38 wrote: »
    as the code is written now it needs a label for the call of the delay_"subroutine" the label named "Init_delaying" and a label where to jump while decrementing the label named "delay_loop" obviously djnz delay_counter, #Init_delaying would create an inifinite loop that would wait endles
    Now we are getting somewhere. As you found out already, djnz can target itself, i.e. djnz value, [#]$.
  • jazzedjazzed Posts: 11,803
    edited 2011-08-04 02:35
    Harprit wrote:
    Using a debugger.

    The general consensus is that the debugger of choice is the PASD debugger by the German group Insonics. The software was written by Andy Schenk and Eric Moyer. It is down loadable from the web site at

    The simplest debugger for beginners is PASD. I don't want my debugger in a beginner's book.
    And if you are not running Windows?

    Then you can use my debugger which does not have a GUI.
  • Heater.Heater. Posts: 21,233
    edited 2011-08-04 03:11
    Harprit,
    Debuggers are very useful but do not replace oscilloscopes, both are needed

    This is totally contrary to the stated target audience for your book. I forget how you phrased it but it seemed to include young people and total beginners with no experience of MCU's, programming or electronics. These folks, like me as a school boy starting out decades ago, will not have access to a scope or the means to get one. Requiring a scope is an immediate barrier to entry.

    Debuggers are useful. However I also think that to require use of one from the beginning is a mistake. At that stage, when the reader hardly know what a program is, or what PASM is, and can barely type a program into the Prop Tool and see it running, a debugger is a completely unfathomable thing that adds more complication to the proceedings than it helps.

    Don't forget all those kids back in the 80's who taught themselves Z80 assembler on Sinclair Spectrums and such like with no such debuggers.

    I managed to create a 8080 emulator on the Prop in PASM with no more debugging aid than the 8 LEDs attached to the Prop. The first textual output I got was the CP/M prompt onto an LCD screen.
  • frank freedmanfrank freedman Posts: 1,839
    edited 2011-08-04 04:07
    Heater. wrote: »
    Harprit,



    This is totally contrary to the stated target audience for your book. I forget how you phrased it but it seemed to include young people and total beginners with no experience of MCU's, programming or electronics. These folks, like me as a school boy starting out decades ago, will not have access to a scope or the means to get one. Requiring a scope is an immediate barrier to entry.

    Debuggers are useful. However I also think that to require use of one from the beginning is a mistake. At that stage, when the reader hardly know what a program is, or what PASM is, and can barely type a program into the Prop Tool and see it running, a debugger is a completely unfathomable thing that adds more complication to the proceedings than it helps.

    Don't forget all those kids back in the 80's who taught themselves Z80 assembler on Sinclair Spectrums and such like with no such debuggers.

    I managed to create a 8080 emulator on the Prop in PASM with no more debugging aid than the 8 LEDs attached to the Prop. The first textual output I got was the CP/M prompt onto an LCD screen.

    Heater, I have not seen the CP/M prompt since I retired/sold my IMSAI years ago. What would it have been worth now I can only guess....

    Nothing should be held up as an absolute requirement. The scope? No, it can not show the content of registers, can not tell the status of flags etc. It can tell you what is happening at an I/O pin, hence my suggestion a few days back to a DS1302 issue. Scope would have shown the (lack of) data stream from the device. Scope can also show what waveform is being created via say an R2R network for D/A conversion. A debugger can show me the contents of the internals of the chip, something a scope could never do. The debugger can show the flow of the program and enable following the path of decisions the logic takes for a given condition. Can not do that with a scope, and since everything is inaccessible not even the most advanced LSA can help. Both tools have their uses, and can be introduced as needed according to the complexity and nature of the problem. In the early days of my IMSAI and also when I was designing and building Z-80 control units, I did not have a scope. Did quite well with a logic probe and understanding what the device should be doing.

    Perhaps the best thing for the beginner is an emulator similar to that of other processors that are out there which allow the user to see all pins and registers, enables modifying things on the fly to do "what if" scenarios, simply watch (though slowly) each step the program takes as it executes. That also allows the beginner to start with minimal cost. No breadboard, no power supply, no propchip or prop plug to let the smoke out of. Just the cost of the media or time if the emulator is open source or at least cheap enough for the beginner to get hold of.

    One size will not fit all, and nothing is a mandatory need to have for many things. There are always workarounds. Just may need to be creative at times.....

    Frank
  • HarpritHarprit Posts: 539
    edited 2011-08-04 07:16
    Heater:

    Thank you so much for writing. It was always my intention to write for the extreme beginners mostly because I do not have the expertise to write for anybody but extreme beginners. I want you to know that I appreciate your bringing me back to my senses. That is what I need to do and that is what I will do.

    Discussions on the board provided tremendous pressure to move away from my initial intention and write for a more sophisticated audience. Write for a steeper learning curve to get one up and writing sophisticated code in a hurry. You would have noticed that initially I resisted the use of a debugger. I relented only because I respect, what Stefan has to say, and his background as a competent and experienced teacher certainly lends considerable weight.

    I have also consistently requested that beginners write and tell us what they are interested in, but the response has been weak. However, I have had some private messages that would tend to indicate that a book very similar to my SPIN book is desired by the beginner crowd. I think these gentlemen and ladies are unwilling to expose themselves to a rather aggressive and more experienced readership, but do want a beginners book that starts from the very elements and build it up from there.

    With the your latest post. I am most motivated and will reconsider the tack that I have taken and go back to my initial ideas of a more basic text for the absolute beginner. Thank you so much for bringing me to my senses and taking me back to my initial target.

    I still want to maintain the ideas that Stephan has stressed. But I do want write for the interests of the absolute beginners.

    As regards. The arguments about whether one needs an oscilloscope or not my personal feeling is that probably, one can do without a debugger in the beginning, but eventually you will want to have a debugger in your arsenal. And if you are interested in electronics. You really do need to own an oscilloscope. It's no different than having a set of wrenches. It is a basic tool for looking into an electronic circuit. Not just microprocessors, but the total electronic circuit. I have a good friend, who is an an expert with things electronic and uses it for everything including as a voltmeter. His oscilloscope comes on when he turns on his workbench. You don't need an expensive oscilloscope, a simple dual trace 5 MHz oscilloscope is more than enough.

    So, let's start from the beginning again, and I will start posting in the vein that I had originally stated I would. I will still need help and commentary, lots of help and lots of commentary. I hope the cognoscenti will oblige.

    Best regards.
    Harprit
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-08-04 07:53
    Harprit,

    Your last post is very encouraging. Go back to thinking like a beginner. Make beginner mistakes. Start simple, have some fun, don't be afraid to code really bad code on your first attempt. It does not matter.

    What matters is trying something out, getting something to work, and then learning along the way.

    You know, I spent all my youth wishing I had a scope. I have one now I can afford one, and it has been useful, but it is not essential. In fact, for digital circuits, I don't think it is needed at all. Ditto debuggers.

    Of course, in a perfect world where beginners have lots of money, you go and buy everything. In the real world, instead of a scope you attach a small amplifier to your signal and listen to it. No, scratch that. You can't afford an amplifier. You attach a 100 ohm resistor in series with an 8 ohm speaker and you listen to that!

    For assembly languages, start simple. Start with just a few instructions and get things working with just those few instructions. Add more instructions later.

    Please keep writing. It may not be perfect and it may have spelling errors, and formatting errors, but I don't think they matter so much.

    Keep up the good work!
  • potatoheadpotatohead Posts: 10,189
    edited 2011-08-04 08:00
    I am sad that there are people reading who would not contribute for those reasons. Gosh, maybe there needs to be a "it gets better" for aspiring electronics and computer programming geeks.

    (because it does you know, really)

    @Harpit, when I wrote the primer, I felt a bit foolish for it's basic presentation. Problem was, I had knocked out probably half of it when this feeling happened. Was "pot committed" so it got completed. I have a lot of nice notes from people who put it to use. Probably a good call on your part, if you've the same kind of queries.

    A suggestion regarding scopes. Never ever present scope only. I think it's very helpful to have scope captures of things to look at. This helps when one does not have a scope. I sure didn't early on, then was given one and the first thing I did was go and examine a whole bunch of things I had pictured in my mind. Great experience. When it eventually died, and I moved on, I did no scope for years. Still got a lot of stuff done the same way it got done the first time, and that is finding ways to confirm without the scope and or just thinking through what must be possible. I've got one now and still use a mix of techniques, just because sometimes the very simple ways of thinking about things and or means and methods are just easy and robust.

    And there are lots of options. Blink the light, listen to the sound, dump a capture of data, display the number, color a scan line real time (that one is damn handy for video related things, because it can be a great timing reference), display the pixels, ping the host, measure the voltage, etc... Then there is the prop as it's own measurement tool. It's so easy to have one COG examine what another one is doing, and the prop itself can do logic probe type things really easy, and there are programs for that purpose too. Don't underestimate the TV driver as output capability. Lots can be done with that, or VGA, which ever makes sense. That is basically what we had in the 80's, and it was plenty.

    If material is presented with all the steps outlined, with scope captures and alternatives detailed, people can visualize, and if they can do that, they can do a lot just by thinking things through, consulting signal references, etc...

    Re: Debuggers. Yep. Didn't have 'em early on. Usually just a monitor, and maybe breakpoints to get a CPU status dump. Even then, I didn't use it much, preferring to look at the instruction data sheet, stepping through things on paper or the blackboard, which a group of us did very regularly learning how to do assembly on the Apple.

    Another approach is to write a program that boot-straps a larger one. Test the core concept, get that working, then once a timing condition is known at the instruction level, cycle counting gets a person a long ways, because cycles are exact, and when people know their units of time for cycles, and can look at pictures of signals, they can often assemble instructions, much like people can draw on graph paper, given some data. Again, that's what I and a lot of peers did.

    So include the scope, but keep the no scope crowd in mind, giving them enough detail to understand what the instructions are doing, and when in relation to the signal they are generating or interacting with is doing.
  • HarpritHarprit Posts: 539
    edited 2011-08-04 08:36
    Let us start over.

    Just like my spin book. My PASM book will be for bonafide beginners.
    The book will be divided into four sections similar to the four sections of my spin book.

    The general outline of the book. The basics, we need to understand PASM, and what we had to work with

    Basic input.
    Basic output.
    Building simple projects.
    Relevant appendices

    The end product will be a basic understanding of PASM and the ability to write simple programs that will be adequate to control small projects.

    Any cog that runs PASM code has to be started from within a cog that are is running SPIN. Here are the few lines of codes needed to start a cog running assembly language. We will be using two commands in the program

    The first command is the mov command. Mov moves data between registers. It moves date from the second register mentioned to the first.
         mov   into,  from
    
    will move whatever is in the "from" register the "into" register. All registers are game.

    The jmp instruction directs program flow. Its lets you jump to any marked location within the program.
    VAR
       long shared_var
       
    PUB Object_name
    cognew(@Prog_start, @shared_Var)
      repeat
    
    DAT  org  0
    Prog_start
    do_again              mov    dira,   init_dira
                               jmp    #do_again
    
    init_dira    long    %00000000_00000000_00000000_00001111
    

    The program sets the DIRA register so that the first four pins of the propeller are set as outputs again and again.

    Here is what we needed to do to accomplish that.

    First we defined a variable in a VAR block

    We have to have at least one public method in the object so we started with naming the method. As soon as we did that we can start the PASM cog with the cognew command and the two @ variables. These two variables tell the program where in the cog to start writing the program and provide an address that will point to a variable that can be shared between SPIN and PASM programs.

    The program itself is described in a DAT data block. The block starts by telling the cog to start the program at location 0 with the Org 0 statement.

    The next two lines are the program. The Prog_start marker is the target of the cognew command mentioned above (the shared variable has not yet been addressed). The first line sets the DIRA register to the value init_dira which is defined as a long at the end of the program.

    The program then jumps back to the do_again line.

    What we have created is a basic program in its absolute minimum. We still have to define all the other blocks that might be needed to support the program that we are going to write and we will add these as we proceed with the learning process.

    Harprit
  • HarpritHarprit Posts: 539
    edited 2011-08-04 18:22
    Turning pins on and off and creating delays.

    Next we need to learn how to turn propeller pins on and off and how to create a timed delay.
    Be warned that there are more elegant ways to do this but we are beginners and so we will stick with easy to understand code as is necessary at this time

    We can turn pins on and off by OR-ing and ANDN-ing them with value we are interested in with the OUTA register once the DIRA register has been defined. The valued we are going to use for the binary manipulations have to have been pre-defined as constants at the tail end of the program. Any number of pins in any pattern can be turned ON or OFF at one time.

    In our previous program we defined pin 0 and pin 1 as outputs. We can turn them on with the OR instruction;. Let us consider pin 1 only for now. We identify this pin with the constant
    pin_1     long   %00000000_00000000_000000_00000010
    
    we can also identify is in decimal and hex notation as follows
    pin_1     long     2
    pin
    
    but for now binary notation will be easier for us and I will use it throughout the book for consistency. A binary notation makes it possible to see the function of each pin at a glance without having to do any mental manipulations.
    Mov     dira,      init_dira        'the original line of code
    or        outa,      pin_1           'the  instruction to turn pin 1 ON
    
    And add the following line at the end of the program to identify pin 1
    pin_1     long   %00000000_00000000_000000_00000010
    
    and we can turn the pin off with the ANDN instruction as follows
    Mov       dira,       init_dira       'the original line of code
    anda      outa,      pin_1           'the  instruction to turn pin 1 OFF
    
    a short program segment:
    do_again        Mov     dira,      init_dira       'the original line of code
                          or        outa,     pin_1           'the new instruction to turn pin 1 ON
                          andn    outa,     pin_1           'the new instruction to turn pin 1 OFF
                           jmp     #do_again
    
    pin_1     long   %00000000_00000000_000000_00000010
    
    The above instructions will turn line 1 on and off about as fast as you can with a propeller. If you look at the line you will notice that the delay between ON and OFF is shorter than the delay between OFF and ON because the JMP instruction takes time as we go through the loop.

    In order to be able to see an LED connected to line 1 go on and off we need a much longer delay. There are a number of ways of creating a delay in PASM but as beginners we can create a conventional delay loop of any length just as we would in a language like BASIC . The code is as follows
    delay             mov      delay_counter,      delay_count      'load the delay counter
    redo              sub       delay_counter,      #1  wz              'subtract 1 and set zero testvalue
              if_z      jmp      #delay_ret                                    'if it is 0 we are done so return from sub
                        jmp        #redo                                           'if not keep subtracting
    delay_ret         ret
    
    This is set up as a subroutine here but you can also use the same technique for in line coding. The subroutine loads the delay value and then keeps subtracting 1 each time through the loop till the value reaches 0. It then returns control to the point from where it was called.

    Whenever you want to call this delay you put in the line
    call #delay
    
    The length of the delay is determined by the constant delay_count which is defined along with other constants at the end of the program. We define a ¼ second delay with a count of 2_000_000 times through the loop. We do this by defining the constant with
    count_delay       long       2_000_000
    
    At 80 MHz, 2 million counts should take 1/40 of a second but we have other instructions that have to be executed in a loop and that adds time to the delay. Making these additions to our program yields the following code.
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    VAR
       long shared_var
       
    PUB Object_name
    cognew(@Prog_start, @shared_Var)
      repeat
    
    DAT  org  0
    Prog_start        mov       dira,     init_dira
                      mov       outa,     init_dira              
    do_again          or        outa,     pin_1                     'the new instruction to turn pin 1 ON
                      call      #delay
                      andn      outa,     pin_1                     'the new instruction to turn pin 1 OFF
                      call      #delay
                      jmp       #do_again
                  
    delay             mov      delay_counter,      delay_count      'load the delay counter
    redo              sub      delay_counter,      #1  wz           'subtract 1 and set zero testvalue
              if_z    jmp      #delay_ret                           'if it is 0 we are done so return from sub
                      jmp      #redo                                'if not keep subtracting
    delay_ret         ret
    
    pin_1             long      %00000000_00000000_00000000_00000010
    init_dira         long      %00000000_00000000_00000000_00000010
    delay_count       long      2_000_000
    
    delay_counter     res       1
    

    Run this program and make changes to see what happens.

    We now know how to write a rudimentary program in PASM. We now know how to turn any propeller line ON and OFF and we know how to add delays into our program when we need to.

    Next we will write a program that will allow us to pass a variable from PASM to SPIN cogs.

    Harprit
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-04 18:37
    Harprit wrote: »
    We can turn pins on and off by OR-ing and ANDN-ing them with value we are interested in with the DIRA register once the DIRA register has been defined.
    Shouldn't the first DIRA read OUTA?
    delay             mov      delay_counter,      delay_count      'load the delay counter
    redo              sub      delay_counter,      #1  wz           'subtract 1 and set zero testvalue
              if_z    jmp      #delay_ret                           'if it is 0 we are done so return from sub
                      jmp      #redo                                'if not keep subtracting
    delay_ret         ret
    
    I'm sure you thought this through, but this is about a wait loop, i.e. keep looping as long as the loop counter is not 0. So wouldn't the following version make more sense?
    delay             mov      delay_counter,      delay_count      'load the delay counter
    redo              sub      delay_counter,      #1  wz           'subtract 1 and set zero testvalue
              if_nz   jmp      #redo                                'if it is <> 0 keep subtracting
    delay_ret         ret
    
  • HarpritHarprit Posts: 539
    edited 2011-08-04 18:40
    Off subject question (in a way

    Is there a font an size I can use that will faithfully copy from word to propeller tool to the discussion forums and preserve all tabs and spacings
    or am I stuck using spaces and a mono spaced font. This has been a real head ache for me so far.

    Harprit.
  • HarpritHarprit Posts: 539
    edited 2011-08-04 18:44
    kuroneko

    Yes you are right on both counts, and it is more elegant. Thanks.
    I will pick these changes up in the book but leave them here so that your comments stay relevant.

    Harprit.

    I changed the DIRA to OUTA, it just bothered me.
  • potatoheadpotatohead Posts: 10,189
    edited 2011-08-04 21:59
    Harpit, I author all code and comments in the Propeller Tool, then copy paste to the other targets. Use Lucida Console for your word processor, so long as you've got none of the Parallax symbols in the code. I actually like the Parallax font for both the symbols, which I would like to use more, and overall readability, but it doesn't render well. It's just fiddly, often not containing the "hints" needed to scale out like it should. The Open Source Vera fonts are a good second choice over Lucida, though I personally don't think they read as well.
  • HarpritHarprit Posts: 539
    edited 2011-08-05 04:49
    Potatohead

    Thanks, the real problem is going from the PT to word and back.
    I will try your suggestions.

    H

    It works real well with a font size of 10. The main problem was going back and forth to open office (which of course the book will be written in).

    H
  • HarpritHarprit Posts: 539
    edited 2011-08-05 05:52
    Using the Full Duplex Serial Object

    Before we start, we need a good way to be able to look into the programs that we are running. One of the best ways of doing this is to send the information to the PST (parallax serial terminal). This terminal appears in a separate window on your monitor when you run the

    Parallax Serial Terminal.exe

    program. We can communicate with this terminal with the FDS (full duplex serial) object that is provided by parallax as a part of the object exchange. This software also comes as one of the programs in the parallax tool editing suite. It is also possible to use the parallax serial terminal program,

    Parallax Serial Terminal.spin

    but the PST uses some non-standard coding, and I avoid it for that reason. The FDS software on the other hand, uses standard serial communications commands and if you are already familiar with them using it is painless. We will use FDS in all our programs that require us to look at what is going on in the program. In fact we will design our programs so that this is one of our primary tools for looking at what is going on in our programs.

    In order to use FDS. You have to have the FDS file in the same folder as the other work that you are doing. If you have not already done so, make a copy of the program and add it to your work folder.

    In your program, list the PDS in the OBJ block with the following lines of code just as you would have done in a SPIN program. As a matter of fact we are going to be running this software in the SPIN cog in our programs.

    OBJ
    fds : "FullDuplexSerial"

    The FDS software is activated within your program by issuing the following command

    fds.start(31,30,0,115200) 'start console at 115200 for debug output

    Once this has been done, all standard commands that a serial terminal accepts are applicable to the FDS. Here is a list of some sample commands that you will need in almost every program. The entire ASCII coding standard is supported.

    fds.bin(P_val,12) 'print value as binary to 12 places
    fds.tx($d) 'new line
    fds.dec(P_val) 'print a decimal value
    fds.tx(" ") 'print a space
    fds.tx($3) 'clear screen and go to 0,0 position
    fds.tx($1) 'go to 0,0 position on screen, do not erase
    'the tx prefix supports the entire ASCII set of commands
    'and alphanumerics.

    It is a good idea to provide one or a few spaces after printing a variable to erase any old information that may be left after the last printout of the same data was made. (This happens when the new output is shorter than the old.)

    Most printing routines are used in a loop that monitors whatever we are interested in. A 1/60 second delay at the end of the loop is adequate for providing a steady flicker free display.

    Harprit
  • potatoheadpotatohead Posts: 10,189
    edited 2011-08-05 07:01
    Yep. I have experienced the same problem. That is why I author all code in the Prop tool and comment. Software is in one branch of work, and in it's folder, numbered to align with chapters, or other references, text in another branch. Typically, I will author software, then write text. Author more software, write more text. Then pause to index, table of contents and clean up. I figure a software download, or separate file will be of use anyway, though I am going to ask them to type a coupla short ones in, just because. :)

    Why are you going from word to PT??
  • HarpritHarprit Posts: 539
    edited 2011-08-05 07:05
    Well, I need to list the programs in word also, for the book text, so I have to go back and forth.
    If the transfer is faithful things are much easier.
    H

    Actually I use dictation software a lot so there is one more step to contend with!

    H
  • potatoheadpotatohead Posts: 10,189
    edited 2011-08-05 07:10
    Ahh! Interesting. Never tried that. Well, that's one way to write with one's own voice!

    I don't understand yet. You are authoring in OO, but a publisher needs word? Is that it?
  • HarpritHarprit Posts: 539
    edited 2011-08-05 07:19
    Actually they are compatible, 100% for what I need but not completely. Diagrams can be problematic sometimes.
    You can go back and forth. But OO is free.
    However McGraw Hill is stuck in the 17th century and prefers that you use a quill.
    For dictation I have Nuance's Dragon for both the Mac and the PC and there is a free app for the iPad which I use occasionally. Spiffy.
    Dragon is really fast but it does misunderstand you once in a while and you have to edit immediately because the mistakes it makes make sense and are often poetic
    and if you don't edit immediately you may never remember what it was you wanted typed.
    H
  • Capt. QuirkCapt. Quirk Posts: 872
    edited 2011-08-05 07:40
    Win 7 comes with a text to voice editor. You go through the same set-up procedures as Dragon. But neither is as easy as you might think.
  • HarpritHarprit Posts: 539
    edited 2011-08-05 07:53
    What did you mean to identify with "neither"
    H
  • HarpritHarprit Posts: 539
    edited 2011-08-05 10:24
    For now, let us set up the following standard for the propeller pins usage.

    Pins 0 to 11 would be connected to 12 LEDs on the PDB
    pins 30 and 31 are reserved for serial communications.
    Pins, 28 and 29 will be left untouched because we don't want to interfere with system operations.
    Pins, 24 to 27 will be connected to the MCP 3208 for reading in the potentiometers that will be used in experiments to come. We will read 4 5K pots eventually
    Pin 23 will be the output for an oscilloscope.
    Pin 22 will be the output for a small speaker.

    This might change from time to time, but for now, you can set this up this way and it should serve for the next few experiments. I will try to stick with this arrangement throughout, but we may have to make changes.

    The oscilloscope and speaker are on separate cogs so that the outputs can be tailored to meet the requirements of each device.

    All the experiments that we do will be able to be done on a simple breadboard. If that is your preference. However, I will be using the PDB, the professional development Board, provided by parallax, because this board has a lot of ancillary devices on it that make it very easy to use. For example, it has 16 LEDs that already have the resistors, they need in the series connected to them. So that making these LEDs active is a simple matter of running jumpers from the propeller pins to the LED pins. There are also resisters on the push buttons and on the switches, which makes life easier. When we need to pull pins up for any number of purposes.

    Setting up the MCP 3208.

    The 3208 is a chip that allows you to read up to eight channels of analog input in a hurry. It is capable of providing about 100,000 conversions per second. If the software to read this device is written in spin. it slows things down considerably. So, we have an interest in writing software in PASM to speed things up. It's not that you can't read one potentiometer quickly in spin its that if you want to read all eight channels, things can get just a bit sluggish.

    In this next exercise we will read channel 0, on the 3208 and display the 12 bits that we read on 12 of the LEDs that be have connected up on the professional development Board. It would be a good idea at this time, if you were to download that data sheet for the 3208 and have it available for easy reference.

    The connections to the 16 pin 3208 are as follows.

    Line 1 Channel 0 Wiper of the 1st potentiometer
    Line 2 Channel 0 Wiper of the 2nd potentiometer
    Line 3 Channel 0 Wiper of the 3rd potentiometer
    Line 4 Channel 0 Wiper of the 4th potentiometer
    Line 5 Channel 0 Wiper of the 5th potentiometer
    Line 6 Channel 0 Wiper of the 6th potentiometer
    Line 7 Channel 0 Wiper of the 7th potentiometer
    Line 8 Channel 0 Wiper of the 8th potentiometer

    Line 9 Ground, main ground
    Line 10 Chip select Pin 24 of the propeller, made an output
    Line 11 Data in Pin 25 of the propeller, made an output
    Line 12 Data out Pin 26 of the propeller, made an input
    Line 13 Clock Pin 27 of the propeller, made an output
    Line 14 Ground Reference Ground
    Line 15 V Ref Reference Volts (5 Volts)
    Line 16 5 Volts 5 Volts power

    The potentiometers we are interested in reading are placed between 5 V and ground and the wipers are connected to pin 1 through 8. Five volts is not mandatory for the potentiometer power but all the pots have to use the same reference voltage in that there is only one input pin for a reference voltage connection. For now we will connect one potentiometer to pin 1 of the 3208.

    The procedure for reading one of the input lines is described in detail in the data sheet . Of special interest is the upper diagram on page 16. Figure 5-1. This figure gives you the timing information that you have to follow in order to be able to read the potentiometers. Essentially, it is a matter of toggling data in and out of the device with the clock bit as various bits are manipulated and read. Read about the procedure in the data sheet before you study the following program so that you will have a better idea of what we are doing here.


    Notes on using PAR command.

    When you start a PASM cog with a command like

    cognew(@generate, @P_Val

    It specifies that whatever long you write to PAL with a command like

    wrlong dat_red, par

    in the PASM cog will be available to be read in the SPIN cog that started the PASM cog with the P_val variable. It is not available to all other SPIN cogs that might have been started immediately before or after the PASM cog. If you want it to be available to other SPIN cogs, create a global variable and then copy P_val to it.

    If you want to share more than one variable, find the address of P_Val and then store the other variables at addresses above the P_Val address. Each long takes 4 bytes so the address are 4 bytes apart. All cogs read the other variables from their addresses.

    You get the address of a variable with

    mov address_of_var, @variable_name

    and

    address_of_var res 1

    at the end of the program to set up the variable storage space


    H
  • HarpritHarprit Posts: 539
    edited 2011-08-05 12:50
    Here is the commented code for last time's discussion
    {{
    Program to read a pot
    August 05 2011
    Sandhu
    Works.
    Using a speaker or the o'scope is optional.
    LEDs show what is being read
    }}
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      spkr_line=22
      osc_line=23
      
    VAR
      long global_value
      long stack1[25]         'space for oscope 
      long stack2[25]         'space for speaker
      
    OBJ 
      fds : "FullDuplexSerial"
      
    PUB null | P_VAL  
    fds.start(31,30,0,115200)       'start console at 115200 for debug output
      cognew(@generate, @P_Val)     'start new cog at "generate" and read variable into P_Val
      cognew(oscope, @stack1)       'open cog to generate osc signals                                                       
      cognew(spkr, @stack2)         'open cog to generate speaker signals
      dira[0 ..11]~~                'set 12 lines are outputs. 12 lines needed for 1.5 bytes
      repeat                        'loop
        global_value:=P_VAL         'endless loop to display data
        outa[0..11] := P_Val        'displays 1.5 bytes of data on the LEDs
        fds.bin(P_val,12)           'print value to the PST                                 
        fds.tx($d)                  'new line                                    
        fds.dec(P_val)              'print value                              
        fds.tx(" ")                 'space
        fds.tx($1)                  'home to 0,0
        waitcnt(clkfreq/60+cnt)     'flicker free wait
    
    PRI oscope                      'oscilloscope output cog
    dira [osc_line]~~               'set pin direcion
      repeat                        'loop
         !outa[osc_line]            'invert line
         waitcnt(clkfreq/(global_value+20)+cnt) 'wait suitable for osc view
    
    PRI spkr                        'speaker oputput cog
    dira [spkr_line]~~              'set pin direcion
      repeat                        'loop
        !outa[spkr_line]            'invert line
         waitcnt(clkfreq/(global_value+20)+cnt)  'wait suitable for speaker
         
    DAT           org       0                       'sets the starting point in Cog
    generate      mov       dira,   set_dira        'sets direction of the prop pins
                  call      #chip_sel_lo            'selects chip by pulling line low
                  call      #Clk_lo                 'START. Clock needs to be low to load data
                  call      #Din_hi                 'must start with Din high to set up 3208
                  call      #Tog_clk                'clk hi-lo to read data           
                  call      #Din_Hi                 'SINGLE DIFF  Low to load
                  call      #Tog_Clk                'toggle clock line hi then low to read in the data                 
                  call      #Din_Lo                 'D2 Low to load input line selection sequence 000 for line 0
                  call      #Tog_Clk                'toggle clock line hi then low to read in the data            
                  call      #Din_Lo                 'D1 Low to load input line selection sequence 000 for line 0
                  call      #Tog_Clk                'toggle clock line hi then low to read in the data           
                  call      #Din_Lo                 'D0 Low to load input line selection sequence 000 for line 0
                  call      #Tog_Clk                'toggle clock line hi then low to read in the data                 
                  call      #Din_Lo                 'blank bit needs a clock cycle, next
                  call      #Tog_Clk                'toggle clock line hi then low to read in the data                
                                                    'next toggle is for the null bit, nothing read
                  call      #Tog_Clk                'toggle clock line hi then low to read in the data          
                  mov       dat_red,  #0            'Clear register we will read data into             
                  mov       count,    #12           'Counter for number of bits we will read
    read_bit      mov       temp,    ina            'read in what is in all the input lines
                  andn      temp,    inputmask wz   'mask off everything except Dout line. Set Z flag    
                  shl       Dat_red,  #1            'shift register left 1 bit to get ready for next bit
            if_nz add       Dat_red,  #1            'if value is still positive add 1 to data register    
                  call      #Tog_Clk                'toggle clock to get next bit ready in Dout
                  sub       count,    #1 wz         'decrement the "bits read" counter. Set Z flag
            if_nz jmp       #read_bit               'go up and do it again if counter not yet 0
                  wrlong    dat_red,   par          'write it in PAR to share it as P.Val
                  call      #Chip_Sel_Hi            'Put chip to sleep by delselecting it, for low power usage
                  jmp       #generate               'go back to do it all again
    
    'Subroutines
    Clk_Hi        or        outa,   clk_bit         'OR it with the Clock Bit to make high
    Clk_Hi_ret              ret                     'return from this subroutine 
    
    Clk_Lo        andn      outa ,   clk_bit        'ANDN it with the Clock Bi to make low
    Clk_Lo_ret              ret                     'return from this subroutine
    
    Tog_Clk       call      #Clk_hi                 'make clock bit high
                  call      #clk_lo                 'make clock bit low
    Tog_Clk_ret             ret                     'return from this subroutine
                                                
    Din_Hi        or        outa ,   din_Bit        'Makes the Din high
    Din_Hi_ret              ret                     'return from this subroutine
                                                  
    Din_Lo        andn      outa ,   din_Bit        'makes Din low
    Din_Lo_ret              ret                     'return from this subroutine
                                                    
    Chip_Sel_Hi   or        outa ,   chs_Bit        'Makes Chip select high
    Chip_Sel_Hi_ret         ret                     'return from this subroutine
                                                  
    Chip_Sel_Lo   andn      outa,   chs_Bit         'makes chip select low
    Chip_Sel_Lo_ret         ret                     'return from this subroutine
                                               
    Read_Next_Bit mov       temp,  ina              'Get the INA register
                  or        temp,  inputmask        'mask all but Din bit
    Read_Next_Bit_ret       ret                     'return from this subroutine
    
    'Constants. This section is similar to the CON block in SPIN           
    Set_dira      long      %00001011_11000000_00001111_11111111   'Set dira register                                 
    Chs_Bit       long      %00000001_00000000_00000000_00000000   'Chip select bit     24
    Din_Bit       long      %00000010_00000000_00000000_00000000   'Data in bit         25
    Dout_Bit      long      %00000100_00000000_00000000_00000000   'Data out bit        26
    Clk_Bit       long      %00001000_00000000_00000000_00000000   'Clock bit           27
    inputmask     long      %11111011_11111111_11111111_11111111   'Mask for reading the Dout bit only 
    Pin_23        long      %00000000_10000000_00000000_00000000   'osc line
    Pin_22        long      %00000000_01000000_00000000_00000000   'Speaker line          
    
    'Variables. This section is similar to the VAR block in SPIN 
    temp          res       1       'temporary storage variable, misc
    count         res       1       'temporary storage variable, read bit counter
    Dat_Red       res       1       'temporary storage variable, data being read
                                           
    
  • HarpritHarprit Posts: 539
    edited 2011-08-05 16:12
    Beginner guys, I need some serious feedback as to how this thing is going.
    If I don't get it this thing could go in the wrong direction.
    If you don't get what you wanted, no feedback will be the reason

    If there is going to be no feedback I might as well write the book and forget about
    posting stuff here. Saves a lot of time and stress.

    H
  • RonPRonP Posts: 384
    edited 2011-08-05 17:33
    Hi Harprit,

    Beginner here.:smile:

    I was following this thread with some interest although I got confused at some point, I don't remember where. I started following it last night again when you said "Lets start over" post #221. The code in post #221 I could follow with your explanation fairly easily. I did make use of the Propeller manual and look up some of commands, I learned something last night about PASM. What you did different there I don't know but I was pretty straight and to the point. Your latest code in post #236 just looks confusing to me and right now I am not into trying to digest it, maybe later.
    I think in the beginning you should stick with simple code you can explain well and then elaborate on different ways of writing the same simple code. For example something I learned last night in post #35 tonyp12 suggests another way of writing the pin mask.
    Pin long %101<<21             'Pin numbers, same as %00000000_10100000_00000000_00000000
    
    I think little bits of information like that would be very helpful using the same simple code. As a beginner I notice a lot of people have different styles of writing code I kinda understand one programmers code because things are done the long way so to speak then someone else's code is completely over my head cause he/she used all the little short cuts like the example above. Eventually it would be nice to understand all the code but. I guess what I am trying to say is explain the simple stuff like Pin long %101<<21 vs. %00000000_10100000_00000000_00000000 in early examples of code that way when you try to explain a more complex instruction you wont bring that << up and make it harder to understand. Did that make sense? We will already have that under our belts.

    On another note, for the new guy PASM is not visually friendly. I would make use of a different type set bold the PASM instructions that way they don't look so mixed in with programmer instruction. Color would be great different things could have a different color. In you SPIN book on page 35 Program Structure I had to break out a magnifying glass to read it my eyes aren't 100% but even you must admit that is some small type. You should make more use of arrows (put some arcs in them to) since PASM jumping around can be hard to follow. Please make example graphics bigger PASM is hard enough to follow for a beginner. For a book to be a good referance one should be able to open it and read its examples easily. Better Graphics is a must IMO. I'll pay extra for color.

    Just my thoughts didn't mean for it to get this long.:smile:

    Ron
  • HarpritHarprit Posts: 539
    edited 2011-08-05 17:43
    Ron

    That was very enlightening for me
    Thank you, just what I need more of.
    Keep it coming.

    HSS
  • HarpritHarprit Posts: 539
    edited 2011-08-05 18:12
    rohorn

    Thanks for the input
    Very helpful
    Keep it coming

    HSS
  • RonPRonP Posts: 384
    edited 2011-08-05 20:38
    Hi Harprit,

    Your code in post #236 I don't know if that code lesson would follow your previous code lesson in the book. IMO they are far apart at least for my basic understanding. I don't know how much an Author can convey with blinking LEDS but to introduce another IC in a PASM lesson would probably confuse me if I wasn't familiar with the chip(MCP 3208) and I am not. I glanced through the PASM section in the Propeller Manual because I don't look there much. I noticed that there are 5 different ADD's and SUB's, as well as other multiple Common Operations(IF_THIS_AND_THAT? C Z?). I am not sure how one would go about it. I would think that using a less complex code example to explain all the different Operators would make more sense. I know the Propeller Manual has examples of these Operators but those are written for someone who has some ASM experience. If I have to read about using the MCP3208 all the good stuff might not sink in. How much can be conveyed using LEDS? Thats the Question. I can get PASM code examples from the OBEX don't need a book for that.

    Ron
  • RonPRonP Posts: 384
    edited 2011-08-05 20:55
    Hi Harprit,
    RE: my previous post.
    I guess what I am trying to say is, after I have spent all the time to set up all the hardware for the lesson and complete it. I am going to ask myself what did I learn was it worth the all trouble of setting it up? Could I have learned that an easier way? The same questions I think you should ask yourself. I don't think interfacing a bunch of hardware is the answer. In the old days people learned Assembly using a monitor or TV, before that probably blinking lights I don't know.

    Just some thoughts, you asked for em.

    Ron

    PS: I am not suggesting your book be a bunch of small code examples. But the first half has a lot of explaining to do. :smile:
Sign In or Register to comment.