Shop OBEX P1 Docs P2 Docs Learn Events
non-parallax advice - Page 2 — Parallax Forums

non-parallax advice

2»

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2014-04-20 15:12
    I think I will put together a YouTube video so people can follow along where turn single led on, and final step is a full-blown pwm trailing led knightrider
    Here is step3, (it does not use OR/ANDN for pins yet) Questions?
    CON
            _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
            _xinfreq = 5_000_000
    
    VAR
      long  symbol                  'not used yet
    
    PUB StartRider
        cognew(@entry,0)            'cognew needs two varibles, the start address of pasm code and a (optional) varible to pass along
    
    DAT
                  org 0
    entry         mov      DIRA,_mypins                   'set LED control pins P16-P23 as output
    main          mov      t1,#7                          'run loop 7 times, so set varible t1 to 7
    loop          mov      OUTA,_pin                      'set the LED we want on
                  mov      t2,cnt                         'copy current Prop Master Counter value to t2
                  add      t2,_delay                      'add a 1/16sec delay                                                                              
                  waitcnt  t2,0                           'tell cog to wait until MasterCounter match t2
    shifter       shl      _pin,#1                        'shift left 7 times and then shift right 7 times.
                  djnz     t1,#loop                       'so do 7 in a row, if not at at 0 jmp to loop
                  xor      shifter,_bit26                 'self-mod the shl into a shr
                  jmp      #main                          'jmp to main, don't forget the #
            
    _bit26        long  1<<26             'same as |<26
    _mypins       long  %11111111<<16     'same as %00000000_11111111_00000000_00000000
    _pin          long  |<16              'same as %00000000_00000001_00000000_00000000  
    _delay        long  80_000_000/16     '80 mill (MHz) divided by 16 = 1/16sec       
    t1            res                     'reserve a temp var, will be initiated to a value by code
    t2            res
    
  • jmgjmg Posts: 15,173
    edited 2014-04-20 16:07
    TC wrote: »
    With everyone help, I have decided to put this board away for a little bit, and use PSAM to get me started learning. Then after I start getting the hang of it, bringing out the Atmel board and start playing with it.

    A useful way to learn Assembler (on any micro), is with a Good Simulator.

    Some of the better tool flows let you mix HLL and the created Assembler, in the Simulator/Debug, but most will give listings of Source and created-Assembler.

    I think the AVR Studio includes a Simulator.

    Another easy-access path into small micros (which can be useful next to a Prop ) is something like TOOLSTICK850-B-SK
    That is ~ $10, and gives you USB-hardware debug access, into a small, sub $1 uC with 12b ADC UART SPI i2c PWM Timers etc.
    Tools are all free.

    useful simulators for this 8 bit core are
    http://www.ieap.uni-kiel.de/surface/ag-berndt/lehre/fpmc/index-e.html
    and
    http://turbo51studio.orgfree.com/downloads/turbo51studio-latest-setup.zip
  • potatoheadpotatohead Posts: 10,261
    edited 2014-04-20 16:16
    I agree with jmg. An alternative is to use a framework, or template where things like getting output or taking input are solved, leaving just the important guts to learn about.

    One of the reasons I did character drivers on the Prop, was to build a little PASM framework like I always had or did on older machines.

    This is also why blinking the LED, then controlling the blink, and finally, blinking in response to input is the "coming of age" trifecta usually able to get somebody going in assembly language.

    On the P1, SPIN is really awesome in how PASM gets loaded onto a COG, making extremely lean, simple and effective PASM programs possible.

    We will very likely have in-line PASM on the next chip, which is the only easier thing I have ever encountered.

    (more, I just realized I need to change batteries... brb, don't want to lose what I have written)
  • tonyp12tonyp12 Posts: 1,951
    edited 2014-04-20 16:21
    IAR Workbench is simulating by default, get the Texas instrument msp430 or 8051 version.
    http://www.iar.com/Products/IAR-Embedded-Workbench/
  • potatoheadpotatohead Posts: 10,261
    edited 2014-04-20 16:59
    The next best thing really is a starter template or two. The one TonyP put out there is a nice start. Adding the basic code to take a value from PAR would flesh it out to be a nice starting point for almost anything.

    From there, it's a one or two strategy approach.

    If you've got a simulator, great! Use it to run your template and understand everything it does. Then, you can take that template, drop new instructions into it and learn what they do.

    If you don't have a simulator, then you work through the template, changing things, and following all of what it does through, until you understand what it's doing. Then, you drop new instructions in, and output results you can use to understand them.

    One basic skill is thinking up quick, clever tests to determine whether or not something is happening. This is the debug LED basically. Based on this, or that, it can be turned on, or off, and with just that LED, you can understand the instructions pretty well, and find out what your program is doing.
  • tonyp12tonyp12 Posts: 1,951
    edited 2014-04-20 17:19
    To be a good asm programmer you must be able to see that it must be a bit pattern somewhere.
    Here is the above code again, but without a loop as it ANDs (TEST) pin variable with %10000001 to see if result is 0.
    DAT
                  org 0
    entry         mov      DIRA,_mypins                   'set LED control pins P16-P23 as output
    main          mov      OUTA,_pin                      'set the LED we want on
                  mov      t2,cnt                         'copy current Prop Master Counter value to t2
                  add      t2,_delay                      'add a 1/16sec delay                                                                              
                  waitcnt  t2,0                           'tell cog to wait until MasterCounter match t2
    shifter       shl      _pin,#1                        'shift left 7 times and then shift right 7 times.
                  test     _pin,_ends wz                  'if pin is at any place of x in 0xxxxxxx0, the result is that z is set 
          if_nz   xor      shifter,_bit26                 'self-mod the shl into a shr
                  jmp      #main                          'jmp to main, don't forget the #
            
    _bit26        long  1<<26             'same as |<26
    _mypins       long  %11111111<<16     'same as %00000000_11111111_00000000_00000000
    _pin          long  |<16              'same as %00000000_00000001_00000000_00000000
    _ends         long  %10000001<<16     'same as %00000000_10000001_00000000_00000000  
    _delay        long  80_000_000/16     '80 mill (MHz) divided by 16 = 1/16sec       
    t2            res   'reserve a temp var, will be initiated to a value by code  
    
  • TCTC Posts: 1,019
    edited 2014-04-24 13:43
    Thank you everyone for the great advice. and thank you tonyp12 for the code, it does help me understand a little better on what is going on.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2014-04-25 01:15
    It certainly doesn't hurt to focus on programing in just one Cog until you see an obvious need for more.

    Assembly language focuses on what the CPU is doing and you have 8 of them available. Too many CPUs doing many things may get you caught up in passing data back and forth rather than in learning to control the CPU.

    When you do move on to more than one CPU, spending a lot of time with just TWO may make sense to fully leaarn how Cogs do share.

    In other words, try to have a study model that offers you the ability to clearly visualize what is going on, and what your resources are really doing.
  • tonyp12tonyp12 Posts: 1,951
    edited 2014-04-25 08:05
    Same function as above, but with a look-up table (resulting that any/many LEDs could be on at the same time as you have complete animation control)
    DAT
                  org 0
    entry         mov      DIRA,_mypins                   'set LED control pins P16-P23 as output
    main          mov      t1,#14                         'run loop 14 times, so set varible t1 to 14
                  movs     animator,#_pin_table           'reset the look-up-table address in self-mod code 0-0, don't forget the mov[b]s[/b] and the #
    loop          mov      t2,cnt                         'copy current Prop Master Counter value to t2
                  add      t2,_delay                      'add a 1/14sec delay                                                                              
                  waitcnt  t2,0                           'tell cog to wait until MasterCounter match t2
    animator      mov      OUTA,0-0                       'set the LED we want on
                  add      animator,#1                    'next table byte (longs are "bytes" in cogs)
                  djnz     t1,#loop                       'so do 14 in a row, if not at at 0 jmp to loop
                  jmp      #main                          'jmp to main, don't forget the #
            
    _pin_table    long  %00000001<<16, %00000010<<16, %00000100<<16, %00001000<<16, %00010000<<16, %00100000<<16, %01000000<<16
                  long  %10000000<<16, %01000000<<16, %00100000<<16, %00010000<<16, %00001000<<16, %00000100<<16, %00000010<<16
    
    _mypins       long  %11111111<<16     'same as %00000000_11111111_00000000_00000000
    _delay        long  80_000_000/14     '80 mill (MHz) divided by 14 = 1/14sec       
    t1            res                     'reserve a temp var, will be initiated to a value by code
    t2            res                     'reserve a temp var, will be initiated to a value by code 
    
  • tonyp12tonyp12 Posts: 1,951
    edited 2014-04-25 16:08
    Same look-up table, but it's in HUB and the array's start @address is passed along with PAR, Spin can now modify the table on the fly as this memory space is continuously read by the cog
    CON
            _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
            _xinfreq = 5_000_000
    
    VAR
      long  pin_table[14]                    ' reserve a 14 long array
    
    PUB StartRider
        PrepareTable                         'run the subroutine below to setup a knightrider animation
        cognew(@entry,@pin_table)            'cognew needs two varibles, the start address of pasm code and a (optional) varible to pass along
    
    PUB PrepareTable
      pin_table[0] := %00000001<<16
      pin_table[1] := %00000010<<16
      pin_table[2] := %00000100<<16
      pin_table[3] := %00001000<<16
      pin_table[4] := %00010000<<16
      pin_table[5] := %00100000<<16
      pin_table[6] := %01000000<<16
      pin_table[7] := %10000000<<16
      pin_table[8] := %01000000<<16
      pin_table[9] := %00100000<<16
      pin_table[10]:= %00010000<<16
      pin_table[11]:= %00001000<<16
      pin_table[12]:= %00000100<<16
      pin_table[13]:= %00000010<<16 
    
    DAT
                  org 0
    entry         mov      DIRA,_mypins                   'set LED control pins P16-P23 as output
    main          mov      t1,#14                         'run loop 14 times, so set varible t1 to 14
                  mov      hubpnt,PAR                     'use the address in PAR that was passed along when cognew
    loop          mov      t2,cnt                         'copy current Prop Master Counter value to t2
                  add      t2,_delay                      'add a 1/12sec delay                                                                              
                  waitcnt  t2,0                           'tell cog to wait until MasterCounter match t2
                  rdlong   OUTA,hubpnt                    'set the LED we want on
                  add      hubpnt,#4                      'next table long (longs are 4 bytes in hub)
                  djnz     t1,#loop                       'so do 14 in a row, if not at at 0 jmp to loop
                  jmp      #main                          'jmp to main, don't forget the #
    
    _mypins       long  %11111111<<16     'same as %00000000_11111111_00000000_00000000
    _delay        long  80_000_000/12     '80 mill (MHz) divided by 14 = 1/12sec
    hubpnt        res                     'PAR is read-only and can not be incremented, plus we need its original value later on anyway
    t1            res                     'reserve a temp var, will be initiated to a value by code
    t2            res                     'reserve a temp var, will be initiated to a value by code
    
Sign In or Register to comment.