Shop OBEX P1 Docs P2 Docs Learn Events
Propeller Learn Start Simple Tutorial — Parallax Forums

Propeller Learn Start Simple Tutorial

microcontrollerusermicrocontrolleruser Posts: 1,194
edited 2017-10-23 00:07 in Propeller 1
Anybody know the code to load a 'register' with a literal value?

The program registers are really 32 bits long?

Then how do we see it?

Debug? Print? Run a debugging session?

Code should be Spin.

Deal with inserting Assembler later.
«1

Comments

  • What is a your definition of a register?

    If you're referring to a named variable, it's easy:
      myVariable := SOME_VALUE
    
    Note the Pascal-inspired assignment operator. User variables can be bytes (8 bits), words (16 bits), or longs (32 bits -- the native type). The compiler will sort out writing to the variable based on its type when you use a simple assignment. Variables that are global to the file are defined in a var section
    var
    
      long  myVar32
      word  myVar16
      byte  myVar8
    
    Variables that are local to a method are always longs, and added to the declaration line of the method:
    some_method(param1, param2) : resultName | local0, local1, local2
    
    All methods return a long -- you don't have to use it. There is an internal return variable called result. You can change the name of result by putting that name after a colon following the method name and [optional] parameters. The result value is always initialized to 0. Local variables are on the stack and not initialized, so you have to do this in the method. You can treat a long like an array of words or bytes using the .word[] an .byte[] modifiers. For example, if you need a local array of eight bytes, you can do this:
    some_method | buffer[2], idx
    
      repeat idx from 0 to 7
        buffer.byte[idx] := idx
    
    Where things can get interesting is if you use a pointer. There is no pointer type in Spin; it's simply a variable that holds the hub address of another variable. We can assign that address at run time with the @ operator.
      p_myVariable := @myVariable
    
    You can update the variable using the pointer -- but you must know the size of your variable; there is no help from the compiler here. If, for example, your variable was a word, you could do this:
      word[p_myVariable] := SOME_VALUE
    

    I find templates useful. My default template (attached) has a few useful objects, including my variant of FullDuplexSerial that I use for debugging. There are a number of formatting methods in the object.


  • Jon

    This is what I'm going by.

    Each Special Purpose Register may be accessed via:
    1)
    its physical register address (Propeller Assembly),
    2)
    its predefined name (Spin or Propeller Assembly), or
    3)
    the register array variable (SPR) with an index of 0 to 15 (Spin).

    Page 24 in Propeller manual 1.2

  • Here is RAM map.

    I was in the wrong place with SFR's.

    See the General Purpose Registers.

    Would like to load one of those.
    1366 x 768 - 230K
  • If you just like to play with these registers and dump out memory etc then it is a very simple matter in Tachyon Forth.

    From a serial terminal type "SPRS 16 DUMPC" which will dump the 16 Special Purpose Registers in the cog.
    To change a register just type "<myval> <myreg> COG!" so to change the FRQA register to 1000 type "1000 FRQA COG!"
    Read the register back with "FRQA COG@ .LONG" where the .LONG will print the value as a hex long.

    All of these sequences can be made into "macros" and executed by name, well, that is one way of looking at how Forth extends
    its dictionary :)

    You may prefer to code in Spin or PASM etc but certainly Tachyon is very useful for exploring the hardware and "what ifs".

  • Jon

    myVariable := SOME_VALUE

    Okay. Got it.
  • Just to reiterate what was mentioned in another thread, it's Propeller, not Propellor.

    -Phil
  • Bob,

    You seem to be overworking the problem. The Propeller is actually quite simple. Remember that code and data live in the same space -- it's all RAM. The SPRs are special (hence the name), but have names to make listings easier to read.

    Want to see a real-world program I wrote today? Another forum member was having problems that lead me to see -- what should have been obvious before -- that my pulse output timing for smart pixels driver didn't account for overhead in the loop. I have this habit of writing small test programs. I needed to verify that my new pulse timing calculation (in Spin) and pulse generation (in PASM) worked as intended. I don't have a 'scope with me so I used one of the counters in the PASM cog to measure the pulse and report its timing (in system ticks). The timing value was written back to the hub so the Spin cog could spit it out to a terminal window.

    Try that with PIC! :)
  • microcontrollerusermicrocontrolleruser Posts: 1,194
    edited 2017-10-16 03:45
    Jon

    Will look at that in a bit.

    Page 40 in manual. Spin section.Very like assembler. In a way.Probably overhead behind it.

    BYTEFILL Fill bytes of main memory with a value; p 57.
    WORDFILL Fill words of main memory with a value; p 234.
    LONGFILL Fill longs of main memory with a value; p 134.
    BYTEMOVE Copy bytes from one region to another in main memory; p 58.
    WORDMOVE Copy words from one region to another in main memory; p 235.
    LONGMOVE Copy longs from one region to another in main memory; p 135

    Getting warm.

    Nice to see MOVE.

    But FILL looks more like it for this.

    Read structure of Propellor.

    Wow! I been telling my colleague. 'All micro's are the same'.

    We will figure this Propeller out!
  • Chip tends to design high-level languages that are tied close the the underlying assembly -- this lets the high-level interpreter be efficient. This is particularly true where there a Spin instructions that directly map to PASM instructions.

  • Jon

    Extracted your source code samples. I will look at them.

    Saying the variable is loaded with an 8 bit or 32 bit literal.

    How do you see it in Propeller Tool?

    DEBUG or PRINT?


  • Jon

    Okay. Ended up really back at your first answer.

    http://learn.parallax.com/tutorials/language/propeller-c/propeller-c-start-simple

    The second to last lesson is PRINT variable values.

    It's C but all languages are the same.

    Also ended up at those Simple C tutorials again.

    Can't hurt to do them.
  • This seems to have some interesting information regarding the registers in the Propeller. This is from the PropGCC Github docs.

    https://github.com/parallaxinc/propgcc-docs/blob/master/doc/InDepth.md

    NOTE:
    " There are no registers like you might find in other processors: all instructions work with a source and a destination memory location. * There is no built-in stack; instead of storing return addresses on a stack, the instruction at the end of a subroutine is modified to jump back to the correct location."

    You might have a look see at gdb to see if you can run a debug session and pull the lower level details out of the code.
  • Nice to see MOVE.

    But FILL looks more like it for this.

    These Spin instructions are for filling (setting the same value into each location of memory) or copying (not moving) a block of memory from one location to another, typically for more than one byte/word/long at a time. They're much faster than a repeat loop for the same purpose.

    You don't need to use these for simple assignments, and since the require memory addresses it's possible to overwrite hub memory and cause your code to fail.

    It might help to think of Propeller cog memory as like a single-column spreadsheet. Each cell of the spreadsheet can contain data (a value) or an instruction (a formula). The Propeller memory locations can have data (a value) or an instruction (like MOV, ADD, etc.). Actually, in a Propeller, an instruction can also be data (with what's called self-modifying code, a very handy feature).

    So there's no designated "code" and/or "data" areas.

    I have several programs in which the temporary variables contain initialization code which is only needed once. I then reuse the locations as needed.

    Extremely flexible.

    Only the top 16 locations (Special Purpose Registers) don't follow this rule, as with most memory-mapped I/O locations.

    Walter


  • Jon

    Extracted your source code samples. I will look at them.

    Saying the variable is loaded with an 8 bit or 32 bit literal.

    How do you see it in Propeller Tool?

    DEBUG or PRINT?

    There are "debugging" objects used by some, but they're really just a wrapper around a serial driver. I tend just to use the serial driver and the various string and numeric formatting methods that are available. I added one called rj_dec() which print s a right-justified decimal value. This is good for neat displays.


  • Jon

    ' "debugging" objects used by some, but they're really just a wrapper around a serial driver'

    Are you getting them right out of the registers (They are called registers in manual) or

    just the 'floating' variable 'reserved RAM space'.?
  • microcontrolleruser,

    If your using Spin then the Parallax Serial Terminal, or PST, object should output most of what you want. It works similar to DEBUG on the BS2.
    ' *** BS2 ---> Spin
    ' DEBUG "Text" ---> pst.Str(string("Text"))
    DEBUG ? variable---> pst.Dec(variable)
    ' DEBUG CR ---> pst.NewLine
    ' DEBUG "Text", CR ---> pst.Str(string("Text", pst#NL))
    ' DEBUG ? IN3 ---> pst.Bin(ina[3],1)
    ' DEBUG ? IN4 ---> pst.Bin(ina[4],1)
    ' DEBUG HOME ---> pst.Clear
    DEBUG CLS ---> pst.Str(string(pst#CS))
    ' DEBUG DEC5 variable ---> pst.Dec(variable)     [5-digit decimal format]
    DEBUG CRSRUP ---> to pst.Str(string(pst#MU))     [cursor up] 
    DEBUG HOME ---> pst.Char(pst#HM)
    DEBUG DEC4 duration ---> pst.Dec(duration)     [4-digit decimal format]
    ' DEBUG CLS ---> pst.Char(pst#CS)
    DEBUG DEC2 counter ---> pst.Dec(counter)     [2-digit decimal format]
    DEBUG HOME ---> pst.Str(string(pst#HM)) 
    DEBUG BIN8 OUTH ---> pst.Bin(outa[8..15],8)
    ' DEBUG DEC4 variable ---> pst.Dec(variable)     [4-digit decimal format]
    ' DEBUG DEC variable ---> pst.DEC(variable)
    
    Just remember that you also need to add the following lines to your Spin program to use PST.
    OBJ ' Added
     pst : "Parallax Serial Terminal" ' Added for DEBUG
    
    PUB Init ' (Added)
     ' Start Parallax Serial Terminal; waits 1 s for you to click Enable button (Added)
     pst.Start(115_200) ' Added for DEBUG
    
  • JonnyMacJonnyMac Posts: 8,926
    edited 2017-10-16 22:47
    See above for general guidance.

    I use my variant of FullDuplexSerial -- PST is a variant of that as well. You have options. I'm very nutty about right justifying values; my serial routines have a method for doing that. If, for example, you wanted to print four-column (value up to 9999), space-padded value with right justification:
      term.rjdec(someVar, 4, " ")
    
    ...where someVar is the name of the variable you want to display. Your Spin programs have access to all the global variables in the file. Local variables are different -- they can only be accessed from within the method where they're declared.


  • Jon

    Have come around to a two prong attack here.

    1 Doing the Learn C Simple examples.

    2 Reading the Assembler section in Propeller manual.

    We'll see what happens.
  • Whatever works. I routinely port pieces of interesting C code to Spin, and -- of course -- one could easily go the other way.

    FWIW... you may find that reading about programming is like reading about swimming; one can't really learn to swim without getting in the water. Likewise, until you do some real work with embedded code, many concepts may not stick (that's been my experience, anyway). When friends ask about learning programming I always suggest having some project goal. Wanting to build something drives practicality into the learning process. Again, that's my experience.
  • Heater.Heater. Posts: 21,230
    Just write some code already!

    I have heard about a lot of reading going on but not about any code being written. Not even getting a LED to flash.

    I agree with JonnyMac that having a goal in mind can be a driving force to roll one's sleeves up and write some code.

    On the other hand it's good to get even the simplest thing working so that you start to get a feel for how feasible your goal is and build some confidence.


  • 'Not even getting a LED to flash.'

    Did too. With my Basic Stamp 1 Project Board.

    It's all the same. There's a little Southern California mysticism to go with the Northern California stuff around here.

    I did the C learn simple first lesson. Okay. I will post the code.
  • Heater.Heater. Posts: 21,230
    Yes, yes, but I thought the idea was to use the Propeller. In Spin or C or assembler. Hence this discussion that has been going on for a month or more.

    Glad to hear you have made some progress.

  • [code]/*
    Hello Message.c

    Display a hello message in the serial terminal.

    http://learn.parallax.com/propeller-c-start-simple/simple-hello-message
    */

    #include "simpletools.h" // Include simpletools header

    int main() // main function
    {
    print("Hello!!!"); // Display a message
    }

    There. I ran that program. On to the next one.
  • Heater.Heater. Posts: 21,230
    Excellent!

  • microcontrollerusermicrocontrolleruser Posts: 1,194
    edited 2017-10-17 19:26
    Here it is. Lesson two.

    Using Quickstart board. It is USB powered. Only using processor. No circuit building.

    Even reading the lesson too. EDIT Using Simple IDE compiler. There are 3 compilers.
    /*
      Variables and Calculations.c
     
      Add two integer values together and display the result.
    */
    
    #include "simpletools.h"                      // Include simpletools
    
    int main()                                    // main function
    {
      int a = 25;                                 // Initialize a variable to 25
      int b = 17;                                 // Initialize b variable to 17
      int c = a + b;                              // Initialize c variable to a + b
      print("c = %d ", c);                        // Display decimal value of c
    }
    

  • What are these?

    Load RAM and RUN

    Load EEPROM and RUN

    Do know EEPROM is 'Electrically Erasable'

    EPROM was Electrically Programmable. Think it took a UV light to erase it.
  • microcontrollerusermicrocontrolleruser Posts: 1,194
    edited 2017-10-17 21:07
    We hooked up board and ran the program.It worked!

    Will read the second part about 'You can also do this with it' later.

    Like the board and the compiler so far!
  • The boot routine in the Propeller's on-chip ROM downloads programs from the attached PC to the on-chip RAM (hub RAM) ready for execution. If you picked the EEPROM option and there were no errors in downloading, the boot routine then copies the program from RAM to the first 32K of the attached external I2C EEPROM. You can have larger EEPROMs and anything above 32K is left as-is. The 1st 32K is verified, then the program is executed (RUN).

  • Mike

    Thanks.You're going to have me rereading that and looking at datasheet and manual.

    Actually I think I got it this last reread. Mental exercise I guess.

    Okay.Let me work on Learn second lesson there.

  • Here's lesson 3.
    /*
      Floating Point Calculations.c
     
      Calculate and display circumference of a circle of radius = 1.0.
    */
    
    #include "simpletools.h"                      // Include simpletools
    
    int main()                                    // main function
    {
      float r = 1.0;                              // Set radius to 1.0
      float c = 2.0 * PI * r;                     // Calculate circumference
      print("circumference = %f \n", c);          // Display circumference
    

    New thing is 'new format placeholder: %f for a floating point value.'

    Then they have you do one more calculation,



Sign In or Register to comment.