Shop OBEX P1 Docs P2 Docs Learn Events
Using cognew more than once referencing the same DAT space — Parallax Forums

Using cognew more than once referencing the same DAT space

R PankauR Pankau Posts: 127
edited 2007-09-27 03:20 in Propeller 1
Is this possible?·
for instance.·

· cog := cognew(@memory, 0)
· cog2 := cognew(@interrupt, 0)

I thought I was on to something when I put another ORG 0 just above the interrupt label and it worked but I think now everything above it is skipped.·· I can't use two ORG 0 directives in the same DAT can I?

So the real question is:· How can one start seperate cogs with different asm functions from a single Spin module?· I wanted to put a very simple routine in a cog to mimic a time interrupt like this.·

interrupt     mov       Time,cnt                                              
              add       Time,timer1
again         waitcnt   Time,timer1
              wrlong    all_ones,ptr_int_flag
              jmp       #again


but I also would like the asm above it to continue to operate in a different cog.·

thanks.

Comments

  • deSilvadeSilva Posts: 2,967
    edited 2007-09-27 01:52
    You can use as many ORG 0 as you want.

    As I explained in my Tutorial, ORG 0 just resets the internal counting of COG cells. That's all. Has nothing to do with memory allocation in the HUB, just with "counting numbers" in the COG. So it makes no sense at all to use anything else but ORG 0.

    When use COGNEW it starts at the address you give loading whatever into the COG from the beginning.

    It's all extraordinary simple!
  • Fred HawkinsFred Hawkins Posts: 997
    edited 2007-09-27 02:04
    R Pankau said...
    Is this possible?·
    for instance.·

    · cog := cognew(@memory, 0)
    · cog2 := cognew(@interrupt, 0)

    I thought I was on to something when I put another ORG 0 just above the interrupt label and it worked but I think now everything above it is skipped.·· I can't use two ORG 0 directives in the same DAT can I?

    So the real question is:· How can one start seperate cogs with different asm functions from a single Spin module?· I wanted to put a very simple routine in a cog to mimic a time interrupt like this.·

    interrupt     mov       Time,cnt                                              
                  add       Time,timer1
    again         waitcnt   Time,timer1
                  wrlong    all_ones,ptr_int_flag
                  jmp       #again
    


    but I also would like the asm above it to continue to operate in a different cog.·

    thanks.
    http://forums.parallax.com/showthread.php?p=615404
    In this thread Chip Gracy's message may·explain·using org. The propeller tool 1.05.7 in the downloads probably has this org embellishment and the $ operator, so don't download his program in this thread.
  • R PankauR Pankau Posts: 127
    edited 2007-09-27 02:06
    Hmmmm· Okay that's good... but· When I add the org 0 for the interrupt bit then it seems to freeze up all of the asm above it.··· without the org everything else works with the exception of the little interrupt routine that does not work.· Like this:

    DAT
    memory        org       0
                  or        outa,SCL_mask           'set clock high
                  or        dira,SDA_mask           'SDA data always 0
                  or        dira,SCL_mask           
                  andn      dira,SDA_mask           'set data high 
                  mov       mem_addr,#0
    read_flags    rdlong    t1,ptr_pendwr                            
                  test      wrpnd_mask,t1 wc   
     
    blah 
    blah
    blah lots of asm...
     
                  org       0
    interrupt     mov       Time,cnt                                              
                  add       Time,timer1
    again         waitcnt   Time,timer1
                  wrlong    all_ones,ptr_int_flag
                  jmp       #again   
    



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • deSilvadeSilva Posts: 2,967
    edited 2007-09-27 02:30
    Where do you define all those variables you use in "interrupt"? (Time, ptr_int:flag,...I They must be after the second ORG of course.
    On the other hand you must not use any variables from the part after the second ORG in "memory" (of course).

    Or post the full code...
  • deSilvadeSilva Posts: 2,967
    edited 2007-09-27 02:40
    From your code...
                  or        dira,SDA_mask           'SDA data always 0
                  or        dira,SCL_mask          
                  andn      dira,SDA_mask           'set data high
    


    This looks funny.. Do you really want to output an SDA pulse of 100 ns? SDA is "pulled-down", I presume..
  • R PankauR Pankau Posts: 127
    edited 2007-09-27 03:02
    probably not, it's inconsequential I believe. just an artifact from removing all of the outa commands. a happy accident that the outa for SCL is zero and with the pullup and using dira to tri-state the output it works.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • R PankauR Pankau Posts: 127
    edited 2007-09-27 03:09
    SDA is the sensitive one here not SCL as I stated.·· I changed things a bit so as to not drive SDA directly.·

    Here is the code
    ·Sounds like I need to make my definitions in different places.· Am I incorrect in my assumption that all reserved words need to be at the end?· or is that just at the end of the respective code that will use it?· I put all definitions at the end of DAT for both routines.
    DAT
    memory        org       0
                  or        outa,SCL_mask           'set clock high
                  or        dira,SDA_mask           'SDA data always 0
                  or        dira,SCL_mask           
                  andn      dira,SDA_mask           'set data high 
                  mov       mem_addr,#0
    read_flags    rdlong    t1,ptr_pendwr                            
                  test      wrpnd_mask,t1 wc        'if write is set the parity is odd and C will be set.
                  'rcl      t2,#1                   'move C into t2
            if_c  call      #write
                  rdlong    t1,ptr_pendre
                  test      wrpnd_mask,t1 wc        'if read is set the parity is odd and C will be set.
                  'rcl      t2,#1
            if_c  call      #read
            
                  jmp       #read_flags
    '--------------------------------------------------------------------------------------------------------------
    write         rdlong    data1,ptr_to_mem        'get data to write to memory {32 bits} store in t2
                  mov       t2,data1
                  rdlong    mem_addr,ptr_memaddr                 
                  mov       t1,mem_addr
                  rol       t1,#16                  'get High byte of Mem address left justified
                  mov       t4,wrcont_byte          'put write control byte in pos for shifting.
                  call      #start
                  call      #cntrl_wr
                  call      #getack
                  call      #send_hi
                  call      #getack
                  call      #send_lo
                  call      #getack
                  call      #snd_data               'send first byte
                  call      #getack
                                                   
                  call      #snd_data               'send second byte
                  call      #getack
                  
                  call      #snd_data               'send third byte
                  call      #getack
                  wrlong    ack,ptr_ack 
                  call      #snd_data                'send fourth byte
                  call      #getack
                  
                  call      #stop
                  wrlong    all_zeroes,ptr_pendwr    'When finished writing clear write pending flag for SPIN
                  add       data1,#1
    '****DEBUGGING CODE*******************************
                  'mov      debug,ack               '*
                              '*
                  'mov      debug,mem_addr          '*
                  'wrlong   debug,data              '*
    '*****DEBUGGING CODE*****************************
    write_ret     ret                                 'Write finished, return to calling routine
    '_________________________________________________________________________________________
    
    read          rdlong    mem_addr,ptr_memaddr
                  mov       t1,mem_addr
                  shl       t1,#16
                  mov       t4,wrcont_byte
                  call      #start                  'START
                  call      #cntrl_wr               'CONTROL BYTE WRITE
                  call      #getack                 'GET 256 ACK
                  call      #send_hi                'SEND HI ADDRESS BYTE
                  call      #getack                 'GET 256 ACK
                  call      #send_lo                'SEND LO ADDRESS BYTE
                  call      #getack                 'GET 256 ACK
                  call      #start                  'START
                  mov       t4,recont_byte          'MOVE READ CONTROL WORD INTO POSITION
                  call      #cntrl_wr               'CONTROL BYTE READ
                  call      #getack                 'GET 256 ACK
                  call      #get_data               'GET DATA BYTE
                  call      #sendack                 'SEND ACK
                  call      #get_data
                  call      #sendack
                  call      #get_data
                  call      #sendack
                  call      #get_data
                  call      #stop                   'NO ACK JUST STOP WHEN FINISHED.  abA
                  wrlong    all_zeroes,ptr_pendre
                  wrlong    t4,ptr_from_mem
    read_ret      ret
    '___________________________________________________________________________________________
                                                  
     '*****SEND START CONDITION******************
    start         andn      dira,SDA_mask           'data 1
                  call      #wait
                  or        outa,SCL_mask           'clock 1
                  call      #wait                                                             
                  or        dira,SDA_mask           'data 0
                  call      #wait
                  call      #wait
                  andn      outa,SCL_mask           'clock 0
                  call      #wait
                  call      #wait
    start_ret     ret
     '*****SEND CONTROL BYTE for WRITE OR READ   **********************
    cntrl_wr      mov       t5,#8                   '8 bits will be shifted.
    wr_cont       shl       t4,#1 wc                'shift into C sending control byte to mem
                  'muxc     outa,SDA_mask           'set SDA to state of C
            IF_C  andn      dira,SDA_mask
            IF_NC or        dira,SDA_mask
                  call      #clock
                  djnz      t5,#wr_cont
    cntrl_wr_ret  ret
    '*******SEND HIGH BYTE OF ADDRESS**************
    send_hi       mov       t5,#8                   'reload to send address high byte.
    hi_byte       shl       t1,#1 wc                'shift high address to C
                  'muxc     outa,SDA_mask           'set SDA to value of C
            IF_C  andn      dira,SDA_mask
            IF_NC or        dira,SDA_mask
                  call      #clock                  'clock out data bit
                  djnz      t5,#hi_byte
    send_hi_ret   ret
                             
    '*******SEND LOW BYTE OF ADDRESS***************
    send_lo       mov       t5,#8
    low_byte      shl       t1,#1 wc                'shift low byte address to C
                  'muxc     outa,SDA_mask           'set SDA to value of C
            IF_C  andn      dira,SDA_mask
            IF_NC or        dira,SDA_mask
                  call      #clock                  'clock out data bit
                  djnz      t5,#low_byte
    send_lo_ret   ret
    '******SEND DATA BYTE*************************
    snd_data      mov       t5,#8                   'send 8 bits per byte
    datbyte       shl       t2,#1 wc                'shift data into C MSB first
                  'muxc     outa, SDA_mask          'set SDA to value of C
            IF_C  andn      dira,SDA_mask
            IF_NC or        dira,SDA_mask
                  call      #clock
                  djnz      t5,#datbyte             'loop 8 times for each byte
    snd_data_ret  ret
    '---------------------------------------------------------------------------------------------------------------
    '_____________________________________________________________________________________
    '  GET DATA BYTE
    get_data      andn      dira,SDA_mask
                  mov       t5,#8
    shftin        or        outa,SCL_mask
                  call      #wait
                  mov       t6,ina
                  and       t6,SDA_mask wc
                  rcl       t4,#1                   'put input bit into C and shif to t4 LSB
                  andn      outa,SCL_mask
                  call      #wait
                  call      #wait
                  djnz      t5,#shftin
                  'or       dira,SDA_mask
    get_data_ret  ret
    '**********************************************************************************
    'SEND ACK
    sendack       or        dira,SDA_mask           'set data to 0
                  'or       dira,SDA_mask           'set data to output
                  call      #clock
    sendack_ret   ret
    
    '***********************************************************************************
    clock         call      #wait
                  or        outa,SCL_mask           'set clock hi
                  call      #wait
                  andn      outa,SCL_mask           'set clock low
                  call      #wait
                  call      #wait
    clock_ret     ret
    '**********************************************************************************
    getack        andn      dira,SDA_mask           'data = input
                  call      #wait
                  or        outa,SCL_mask           'clock data from mem
                  call      #wait
                  mov       t6,ina                  'get ack from mem
                  and       t6,SDA_mask             'just want SDA only
                  andn      outa,SCL_mask           'clock low
                  test      t6,all_ones wz          'should be Zero for ack
            if_z  mov       ack,#0                  'ack of zero is evidence of active chip
            if_nz mov       ack,#1                  '  SDA line has 10k pullup. 
                  'or       dira,SDA_mask           'set data back to out
                  call      #wait
                  call      #wait  
    getack_ret    ret
    '************************************************************************************
    wait          mov       Time,cnt
                  add       Time,Delay
                  waitcnt   Time,Delay
    wait_ret      ret                                      
    '*************************************************************************************
    '***************************************************************************************
    stop          or        dira,SDA_mask           'data 0
                  andn      outa,SCL_mask           'clock 0
                  call      #wait
                  or        outa,SCL_mask           'clock 1
                  call      #wait
                  andn      dira,SDA_mask            'data 1
                  call      #wait
                  call      #wait
                  call      #wait
                  call      #wait
    stop_ret      ret
    
    'THIS RUNS IN A SEPERATE COG TO SIMULATE AN INTERRUPT EVERY 200,000 CYCLES OR 1/100 SECOND.
    interrupt     'org      0
                  mov       Time,cnt                                              
                  add       Time,timer1
    again         waitcnt   Time,timer1
                  wrlong    all_ones,ptr_int_flag
                  jmp       #again
    
    all_ones      long      $FFFFFFFF
    all_zeroes    long      0
    Delay         long      14                      'approx 700 nano-seconds
    Log_SCL       long      26
    Log_SDA       long      27
    ptr_to_mem    long      0
    ptr_from_mem  long      0
    ptr_pendwr    long      0
    ptr_pendre    long      0
    ptr_memaddr   long      0
    ptr_ack       long      0
    ptr_int_flag  long      0
    wrpnd_mask    long      %1
    SCL_mask      long      %00000100_00000000_00000000_00000000   'P26
    SDA_mask      long      %00001000_00000000_00000000_00000000   'P27
    mem_addr      long      0
    wrcont_byte   long      %10100000_00000000_00000000_00000000
    recont_byte   long      %10100001_00000000_00000000_00000000
    timer1        long      200_000                                '1/100 second
    'Debugging variables
    hibyte        long      0
    lobyte        long      0
    data1         long      $33779912
    str1          byte      "=control ",13,10,0
    str2          byte      "=Hibyte",13,10,0
    str3          byte      "=ack ",13,10,0
    str4          byte      "=data",13,10,0
    t1            res       1
    t2            res       1
    t3            res       1
    t4            res       1
    t5            res       1
    t6            res       1
    b1            res       1
    Time          res       1
    Debug         res       1
    ack           res       1
    
  • hippyhippy Posts: 1,981
    edited 2007-09-27 03:16
    R Pankau said...
    I put all definitions at the end of DAT for both routines.

    That will likely be your problem. The Cog addresses allocated to the data after the second ORG may well be the same as those used by code before that second ORG.

    What you want is ...

    DAT

    ORG 0
    First Assembler Code
    Data associated with this Code

    ORG 0
    Second Assembler Code
    Data associated with this code
  • R PankauR Pankau Posts: 127
    edited 2007-09-27 03:20
    Works!
    Thanks!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sign In or Register to comment.