Shop OBEX P1 Docs P2 Docs Learn Events
P2 A Beginning — Parallax Forums

P2 A Beginning

kg1kg1 Posts: 164
edited 2020-03-16 01:02 in Propeller 2
This works ok:
PUB MinimalSpin()
  REPEAT
    PINWRITE(63..56, GETRND())  'Needs extra brackets
    WAITMS(100)
This is a modification:
PUB MinimalSpin()
  REPEAT
    PINWRITE(63..56, GETRND())
    WAITCT(2_000_000 + GETCT())
This does not work:
PUB Toggle() | temp
  dira[60]~~
  repeat
    temp := !outb[60]
    WAITCT(2_000_000 + GETCT())
temp added to avoid error with !outb[60]
Will not run?
Any suggestions please.
Kevin.

When editing this post I can see the file attached below. Prior to entering edit mode it had disappeared!

Comments

  • cgraceycgracey Posts: 14,133
    edited 2020-03-15 23:37
    Instead of...

    temp := !outb[60]

    ...do this...

    outb[60]!

    Look in the Google Doc of the Spin2 documentation and review the Operators section. It's all in there.
  • @cgracey Thanks Chip.
  • Compiles but will not run:
    PUB Toggle()
      dira[60]~~
      repeat
        outb[60]!
        WAITCT(2_000_000 + GETCT())
    
    
    {{
    TYPE: METHOD          VALUE: 00000000          NAME: TOGGLE
    TYPE: CON             VALUE: 00000000          NAME: CLKMODE_
    TYPE: CON             VALUE: 01312D00          NAME: CLKFREQ_
    
    
    CLKMODE:   $00000000
    CLKFREQ:  20,000,000
    XINFREQ:           0
    
    
    OBJ bytes:          28
    VAR bytes:           4
    
    00000- 08 00 00 80 1B 00 00 00 00 A0 4E 36 81 4E 39 8B   '..........N6.N9.'
    00010- 49 80 84 1E 00 33 8A 35 11 74 04 00               'I....3.5.t..'
    }}
    
  • cgraceycgracey Posts: 14,133
    dira[60]~~

    Make it dirb, instead.

    And remember that those registers only have bits that go up to 31, So when you say 60, that top bit is being ignored, making it really bit 28 of dirb/outb.
  • kg1kg1 Posts: 164
    edited 2020-03-16 00:58
    Finished code:
    PUB Toggle()
      dirb.[28]~~
      repeat
        outb.[28]!
        WAITCT(2_000_000 + GETCT())
    
    Pin 60 is bit 28 in registers DIRB and OUTB
    To use a bitfield we need a dot in front of the square brackets that is .[28]
    Modified file attached.
    The first file attached was not deleted. For me in FireFox it has disappeared. Lets hope the file below remains attached to this post!
  • cgraceycgracey Posts: 14,133
    kg1 wrote: »
    Finished code:
    PUB Toggle()
      dirb.[28]~~
      repeat
        outb.[28]!
        WAITCT(2_000_000 + GETCT())
    
    Pin 60 is bit 28 in registers DIRB and OUTB
    To use a bitfield we need a dot in front of the square brackets that is .[28]
    Modified file attached.
    The first file attached was not deleted. For me in FireFox it has disappeared. Lets hope the file below remains attached to this post!

    Ah, yes, I forgot about the period that needs to go in front of the brackets.
  • kg1 wrote: »
    Modified file attached.
    The first file attached was not deleted. For me in FireFox it has disappeared. Lets hope the file below remains attached to this post!

    Since I'm also using Firefox (under W 8.1/64) and I am able to see both, perhaps any "cached-alike" effect can be taking effect here.

    As for Firefox options settings, I've forced it to wipe everything, acording to my settings, each time Firefox closes.

    But there is a trick (eh eh eh, there is ealways one): I always; repeating to be clear, always use Ccleaner, after closing Firefox, or any other browser (I do it not very often; perhaps twice a day, or three times, maximum).

    And you bet, there is an interesting symptom, that happens to show, not every time a Firefox session is closed, but very often indeed: Ccleaner complains that Firefox is still open, in the background, and asks me if I want it (Ccleaner) to close the unnoticeable session for me.

    By inspecting with task manager, there is indeed a unclosed, ghost-alike session, under the hood, so I instruct Ccleaner to close it, and continue whith its cleanse/wipe task.

    After Ccleaner does its job, I always re-start my system (seems paranoid, but, normally, just before lunch and dinner, and just one more, during the high-night-ours period, if I stay connected a "little more")

    There are other possibilities, including intermediate caches, between your access point and the forum web server, but those are beyoud our arms reach...
  • I think this example is working ok:
    {{ Blinker1.spin }}
    
    OBJ
      LED : "Output"
    
    PUB Main()
    {Toggle pins at different rates, simultaneously}
      LED.Start(28, 3_000_000, 80)
      LED.Toggle(29, 4_000_000, 100)
    
    {{ Output.spin }}
    
    VAR
      long  Stack[9]             'Stack space for new cog
      long  cog
    
    PUB Start(Pin, Delay, Count)
    {{Start new toggling process in a new cog.}}
    
      cog := COGSPIN(16+32, Toggle(Pin, Delay, Count), @Stack)
    
    PUB Toggle(Pin, Delay, Count)
    {{Toggle Pin, Count times with Delay clock cycles in between.}}
    
      dirb.[Pin]~~                  'Set I/O pin to output direction
      repeat Count                  'Repeat for Count iterations
        outb.[Pin]!                 '  Toggle I/O Pin
        WAITCT(Delay + GETCT())     '  Wait for Delay cycles
    
    What are the rules regarding the parameter cognum?
    Have I treated the parameter Pin 60 correctly?

    Many thanks,
    Kevin.
  • JonnyMacJonnyMac Posts: 8,926
    edited 2020-03-19 21:58
    For readability, I would suggest...
    pub toggle(pin, delay, count)
    
    '' Toggle pin count times, with delay cycles in between
    
      pinlow(pin)                                                   ' start low                                                                                                
    
      repeat count
        pintoggle(pin)
        waitct(getct() + delay)
    
      pinfloat(pin)                                                 ' disconnect after use
    
    Spin2 is a bigger language than Spin1 and has keywords that make the this kind of code easier to follow. You may also consider using something other than counts for timing which makes the delay clkfreq-independent -- you have a choice of milliseconds or microseconds. For example...
    pub toggle(pin, delay, count)
    
    '' Toggle pin count times, with delay milliseconds in between
    
      pinlow(pin)                                                   ' start low                                                                                                
    
      repeat count
        pintoggle(pin)
        waitms(delay)
    
      pinfloat(pin)                                                 ' disconnect after use
    
    If you don't care about the starting state of the pin you can take out the pinlow(pin) as pintoggle(pin) will set it to output mode.
  • kg1kg1 Posts: 164
    edited 2020-03-21 00:01
    @JonnyMac Thank you Jon.
    Have you used COGSPIN?
    Kevin
  • JonnyMacJonnyMac Posts: 8,926
    edited 2020-03-20 15:57
    Only a little bit. I don't yet understand why one would use +32 (hub exec) unless is to run a PASM2 program larger than can fit in the cog; the cog is still busy running that code, no matter its location.

    There are no comments in this code, but this is a "traditional" SpinX object with start() and stop() methods. Since you could set count to something like POSX, there is a method that returns true if the blinker is running.

    Edited
    ''' blinker.spin2
    
    
    con
    
      COGEXEC_NEW = 16                                              ' remove for PNut v34p+
      
    
    var
    
      long  cog
      long  stack[16]
      
      
    pub null()
    
      ' This is not a top object
    
    
    pub start(pin, delay, count) : result
    
      stop()
    
      cog := cogspin(COGEXEC_NEW, blink(pin, delay, count), @stack) + 1
    
      result := (cog >= 0)
    
    
    pub stop()
    
      if (cog)
        cogstop(cog-1)
        longfill(@cog, 0, 17)
    
    
    pub running() : result
    
      result := (cog > 0)
    
    
    pri blink(pin, delay, count)
    
      repeat count
        pintoggle(pin)
        waitms(delay)
    
      cog := 0
      cogstop(cogid())
    
  • Thank you Jon for your help.
    In @cgracey document he has:
    'COGINIT(16, @IncPins, 0) will launch this program in a free cog
    'COGINIT(32+16, @IncPins, 0) will launch this program in a free cog
    but nothing about COGSPIN. COGINIT is for running asm and COGSPIN is for running spin2.
    I do not understand why in one function he used 16 and in another 32+16. How do these relate to cognum?
    I guess if one sets cognum in the range 0 to 7 then the function will run in that specific cog, if it is not in use.
    If one wants any free cog auto select, then cognum should be set to ....
    I will use your print object to check which values qualify.
    Kevin.
  • cgraceycgracey Posts: 14,133
    I just added symbols to Spin2 to cover COGINIT and COGSPIN. They aren't in PNut_v34o, but they will be in the coming v34p.

    COGINIT_Symbols.png
    1134 x 526 - 22K
  • cgraceycgracey Posts: 14,133
    Hmmmm....

    Would it be better if the labels were:

    COGEXEC
    HUBEXEC
    COGEXEC_NEW
    HUBEXEC_NEW
    COGEXEC_NEW_PAIR
    HUBEXEC_NEW_PAIR
  • JonnyMacJonnyMac Posts: 8,926
    edited 2020-03-20 15:55
    I do not understand why in one function he used 16 and in another 32+16. How do these relate to cognum?
    I think he was just showing available examples. And, I'm not sure HUBEXEC (32) applies to Spin cogs, anyway; in that case the interpreter is running in the cog and the code is already in the hub. Again, I think HUBEXEC exists for PASM programs that will not fit in the hub.

    @cgracey Can you confirm, please? And I would go with the second set of labels.
  • cgracey wrote: »
    Hmmmm....

    Would it be better if the labels were:

    COGEXEC
    HUBEXEC
    COGEXEC_NEW
    HUBEXEC_NEW
    COGEXEC_NEW_PAIR
    HUBEXEC_NEW_PAIR

    I think these are better.
  • Thank you @cgracey that is really great to receive.

    For those who wonder what I am about:

    I believe that human beings may be categorized as word persons (say 60%) or arithmetic / logic persons (say 30%) and the balance a not so common mixture of both. Word persons generally love writing or receiving reports and rarely implement or build anything. Logic persons do not enjoy writing words and cannot see the point of writing long descriptive prose that describes what is fundamentally logical.

    At secondary school I loved mathematics. My maths teacher was inclined to send me home rather than have me present in his classes. He never asked me how I knew so much. To me the answer was that I read the textbooks the night before class. In my third year the school was worried that I would not pass the external exams which required a 30% pass rate in English or fail all papers. Even though it was a government school they employed a teacher just to teach me English / grammar for a year. I passed English with 32%. Am I a word person or a logic person? The school had no idea that my much loved grandmother was killed, in daylight, by a drunk driver just 300 meters from the school. My school leaving testimonial was unusable.

    If a dozen children rush into a room, perhaps not seen for a year, I would have great difficulty recalling their first names. At times I can go completely blank trying to remember even simple words. The best ideas come in a flash when I am not trying to think of a solution.
    Regards,
    Kevin.
  • kg1 wrote: »
    If a dozen children rush into a room, perhaps not seen for a year, I would have great difficulty recalling their first names. At times I can go completely blank trying to remember even simple words. The best ideas come in a flash when I am not trying to think of a solution.

    Ey, that's me! Altough I am great at finding solutions for problems I'm not actually facing :)
  • An example for cog usage:
    '' =================================================================================================
    ''
    ''   File....... kg1 start.spin2
    ''   Purpose.... Template
    ''   Author..... Kevin Gordon
    ''   Started.... 22 April 2020
    '' =================================================================================================
    
    
    con { timing }
    
      CLK_FREQ = 200_000_000                                        ' system freq as a constant
      MS_001   = CLK_FREQ / 1_000                                   ' ticks in 1ms
      US_001   = CLK_FREQ / 1_000_000                               ' ticks in 1us
    
      BR_TERM  = 115_200                                            ' terminal baud rate
    
      _clkfreq = CLK_FREQ                                           ' set P2 clock
    
    
    con { fixed io pins }
    
      RX1   = 63  { I }                                             ' programming / debug
      TX1   = 62  { O }
    
    con
    
      #true, ON, OFF                                                ' digital control
      #0, NO, YES
    
    
    obj
    
      term : "jm_serial"                                            ' for terminal output
    
    var
      long cog
      long start
      long data
      long data2
      long answer
    
    pub main() | device, addr, slaveid, result
    
      setup()
      wait_for_terminal(true)
      term.str(@Header)
    
      start := YES
      data := 200
      data2 := 36500
      cog := COGINIT(COGEXEC_NEW, @startasm, @data)
      term.str(string(" cog: "))
      term.dec(cog)
      term.tx(13)
      repeat while start == YES
      term.fstr3(string(" %d + %d = %d\r"), data, data2, answer)
      term.tx(13)
      cog := COGCHK(cog)
      IF cog == 0
        term.str(string("Done"))
    
      repeat
        waitct(0)
    
    pub wait_for_terminal(clear)
    
      term.rxflush()
      term.rx()                                                     ' wait for keypress
      if (clear)
        term.tx(term.CLS)
    
    pub setup()
    
      term.start(BR_TERM)                                           ' start terminal io
    
    dat
    
      Header        byte    "P2X8C4M64P", 13, 13
                    byte    " Testing addition!", 13
                    byte    0
    
      org
    startasm
      rdlong value, ptra    'get first value
      add    ptra, #4       'move over to pick up the next value in the next long
      rdlong value2, ptra   'get second value
      add value2, value
      mov value3, value2    'move to answer var in next long
      add ptra, #4
      wrlong value3, ptra   'write it to the pointer
      sub ptra, #12          'point back to the orginal data
      wrlong #0, ptra       'tell original cog we are finished
      cogid value
      cogstop value
    
    value long 0             'data
    value2 long 0            'data2
    value3 long 0            'answer
      
    con { license }
    
    {{
    
      MIT License
    
      Copyright (c) 2020 Kevin Gordon
    
      Permission is hereby granted, free of charge, to any person obtaining a copy
      of this software and associated documentation files (the "Software"), to deal
      in the Software without restriction, including without limitation the rights
      to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      copies of the Software, and to permit persons to whom the Software is
      furnished to do so, subject to the following conditions:
    
      The above copyright notice and this permission notice shall be included in all
      copies or substantial portions of the Software.
    
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      SOFTWARE.
    
    }}
    
    Improvements please.
    Kevin
Sign In or Register to comment.