Shop OBEX P1 Docs P2 Docs Learn Events
memory colision on a single byte — Parallax Forums

memory colision on a single byte

courtenscourtens Posts: 101
edited 2011-12-26 15:46 in Propeller 1
Is this possible? Do it need a lock just for ONE byte?

I am using a byte to keep track if I am getting a PAL or NTSC video signal input - this is running in its separate cog. But as soon as I am running PWM_Nctrx object by Tracy Allen, also running in its separate cog, I am getting some strange behavior on my byte that holds that PAL or NTSC value.

Can anyone help?

I could provide more of the code, but it's messy and long.
PUB cog_motorPWM
                
  cog_motorPWM_COGID := COGID
  
  repeat                 
    PWM.PWMctrx2(motor_pin,motorspeed,testpercent)
                
PUB cog_video | tmp, start_time, stop_time  

  {{
  detects video type (NTSC, PAL, or missing) signal input
  will return
      
          PAL_or_NTSC_value 0 for missing signal 
          PAL_or_NTSC_value 1 for PAL
          PAL_or_NTSC_value 2 for NTSC   
  }}                                                              
  
  cog_video_COGID := COGID
                                                                          
  repeat             
    tmp:=cnt                                              'assign temporary time stamp
                                                          'to break out of repeat loop if not video signal is present                                                 
    repeat while ina[video_pin]==0                        'hold at low
      if 6_000_000<(||(cnt-tmp))    
        quit                                              'brake out of repeat loop
    start_time:=cnt                                       'time stamp on just went high
    tmp:=cnt                                              'reassign temporary time stamp
                                                          'to break out of repeat loop if not video signal is present                                                                                           
    repeat while ina[video_pin]==1                        'hold at high                              
      if 6_000_000<(||(cnt-tmp))                   
        quit                                              'brake out of repeat loop
    tmp:=cnt                                              'reassign temporary time stamp
                                                          'to break out of repeat loop if not video signal is present  
    repeat while ina[video_pin]==0                        'hold at low
      if 6_000_000<(||(cnt-tmp))         
        quit                                              'brake out of repeat loop  
    stop_time:=cnt                                        'time stamp on just went high again
    
    if stop_time>start_time                               'read timer differance   
      elapsed_time:=stop_time - start_time
    else
      elapsed_time:=(POSX - start_time)+(POSX + stop_time)               
                                                                                                                                                         
    if elapsed_time>3_300_000                                  
      PAL_or_NTSC_value:=0                                'no video signal   
    elseif elapsed_time>2_700_000                          
      PAL_or_NTSC_value:=1                                'is PAL    
    else                                                       
      PAL_or_NTSC_value:=2                                'is NTSC    


Thanks !!!

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-26 09:15
    When you start the cog_video cog, how big of a stack do you allocate for it?

    -Phil
  • courtenscourtens Posts: 101
    edited 2011-12-26 09:23
    50
    VAR 
      long Stack1[50]                                       'this RAM will be assigned to COG1
      ...
    
    PUB Go 
      cognew (cog_video, @Stack1)                           'create COG_video
      ...
    
  • courtenscourtens Posts: 101
    edited 2011-12-26 09:40
    I just dicovered that I am using 1320 bytes for my main cog.
    Would this be 1320 bytes / 4 = 330 long (?)
    How do I assign space for that main (first) cog?

    This the PWM_Nctrx object by Tracy Allen:
    CON                             
      percentStep = 42949672                                ' 2^32 / 100 for steps of one percent phase offset
    
    VAR
    
    OBJ
    
    PUB PWMctrx2(pin,freqHz,percent) | frqx                 ' entry with frequency in Hz
      frqx := fraction(freqHz,clkfreq,32)                   ' calculate angular frequency
      PWMctrx2a(pin,frqx,percent)
    
    PUB PWMctrx2a(pin,frqx,percent)                         ' entry with angular frequency in counts per clock tick
      dira[pin..pin+1]~~                                    ' pin for PWM, second pin for external XOR inverter
      frqa := frqb := 0                                     ' don't advance during parameter update
      if percent<50                                         ' invert if PWM needs to be less than 100%
        outa[pin+1]~~
      else
        outa[pin+1]~
      percent := 50-percent                                 ' adjust for offset of counter phases, no overlap at 50%
      phsb := phsa + percentStep * percent
      frqa := frqb := frqx
      ctra := constant(%00100 << 26) + pin
      ctrb := constant(%00100 << 26) + pin
    
    PRI fraction (y, x, b) : f                              ' calculate f = y/x * 2^b
                                                            ' b is number of bits
                                                            ' enter with y,x: {x > y, x < 2^31, y <= 2^31}
                                                            ' exit with f: f/(2^b) =<  y/x =< (f+1) / (2^b)
                                                            ' that is, f / 2^b is the closest appoximation to the original fraction for that b.
      repeat b
        y <<= 1
        f <<= 1
        if y => x    '
          y -= x
          f++
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-26 10:17
    Fifty longs should be enough for the stack.
    courtens wrote:
    How do I assign space for that main (first) cog?
    You don't. It's automatic.

    Perhaps it would be best, at this point, to post your entire program. Just archive it, and attach the resulting zip file.

    -Phil
  • courtenscourtens Posts: 101
    edited 2011-12-26 10:25
    I like the archival tool! Learning something every day.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-12-26 10:29
    To answer your original question ... Yes, you need a lock for a single byte or a word or a long ... sometimes.

    The main issue is that two cogs can possibly access the storage unit at the same time. You can get into trouble if either of two (or more) cogs can change the value of the storage unit or if one cog reads the value of the storage unit twice expecting the value to be the same both times, yet another cog can change the value of the storage unit between the two times it's read. There are other variations of the problem, but these are the most common cases.

    It's possible to have two cogs share a common variable if some rules are followed. This is the producer-consumer case which doesn't need a lock (semaphore). There's a good article in the Wikipedia on this.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-12-26 10:47
    courtens,

    Nothing in your code really sticks out as problematic. Only one method is setting PAL_or_NTSC_value, so no locks are necessary. Have you tried the program with the PWM module running but without a motor connected? I wonder if there might be motor noise coming in on the video input line.

    -Phil
  • courtenscourtens Posts: 101
    edited 2011-12-26 11:12
    Thanks Mike -- I do have a "producer-consumer case" setup --- so it should not be a memory collision problem.
    The problem starts appearing as soon as play_FW_pin or play_RW_pin goes high.
    These some screen-shots that show how the array starts displaying misshaps.

    Normal state - No video signal
    DSCN0641.JPG


    Normal state - PAL
    DSCN0639.JPG


    Normal state - NTSC
    DSCN0638.JPG


    Problem appears as soon as I put play_FW_pin or play_RW_pin to high (array to the left starts showing new values outside of PAL or NTSC range)

    This for PAL: value of 1596608 or 1599056 should not be there.
    DSCN0640.JPG
    360 x 270 - 42K
    360 x 270 - 45K
    360 x 270 - 38K
    360 x 270 - 38K
  • courtenscourtens Posts: 101
    edited 2011-12-26 11:23
    Thanks Phil !
    courtens,
    I wonder if there might be motor noise coming in on the video input line.
    -Phil

    I was wondering if adding an extra cap would help prevent any bounces from occurring. I do have the signal go though a CD4066 switch with a 1M pull down resistor on the 3.3DCV side. On the other side (away form the propeller chip) I am sing LM1881 to give me ODD/EVEN for each video frame. That should be clean.

    Never the less, I am using video input on P1 and motor output on P2 .... could that be causing the problem?
  • courtenscourtens Posts: 101
    edited 2011-12-26 11:37
    Phil - you're right !

    the noise is around 290mV but peeks up to 648mV at times -- right after it falls back to "0". I would need to check if a pull down would help keep the low lower.
  • Clive WakehamClive Wakeham Posts: 152
    edited 2011-12-26 15:02
    Mike Green wrote: »
    To answer your original question ... Yes, you need a lock for a single byte or a word or a long ... sometimes.

    The main issue is that two cogs can possibly access the storage unit at the same time. You can get into trouble if either of two (or more) cogs can change the value of the storage unit or if one cog reads the value of the storage unit twice expecting the value to be the same both times, yet another cog can change the value of the storage unit between the two times it's read. There are other variations of the problem, but these are the most common cases.

    It's possible to have two cogs share a common variable if some rules are followed. This is the producer-consumer case which doesn't need a lock (semaphore). There's a good article in the Wikipedia on this.

    I used a lock for my object for keypad scanning for the 74c92X chips.
    I think it was the first thing I put in to stop clashes during memory reads and writes.
  • courtenscourtens Posts: 101
    edited 2011-12-26 15:18
    OK - I cleaned up the video signal input. I added a 11nF cap and a 100K resistor to clean out the spikes, I also added some distance to the lines (the video signal line and motor trigger line used to run parallel for some distance -- not anymore.)

    The bad news is that the error did not go away. I am still getting the same errors. It must be code related and must be somewhere in the cod_video section of the code.
  • courtenscourtens Posts: 101
    edited 2011-12-26 15:46
    It looks like I finally got it to work. It is not a memory collision problem icon11.png but a propeller beeing too fast speep issue (nice!)

    The out shot: "repeat while" takes to little time to process -- and is prone of producing miss-reads with noisy signals.

    I fixed it by adding a delay - waitcnt after my time stamp.
    repeat             
        tmp:=cnt                                              
                                                                                                             
        repeat while ina[video_pin]==0                       
          if 5_000_000<(||(cnt-tmp))    
            quit                                            
        start_time:=cnt                                     
        tmp:=cnt                                             
    
        waitcnt(1_000_000+cnt)                                '//  new  
                                                                                                                                                        
        repeat while ina[video_pin]==1                                                      
          if 5_000_000<(||(cnt-tmp))                   
            quit                                              
        tmp:=cnt                                              
         
        waitcnt(1_000_000+cnt)                                '//  new
        
        repeat while ina[video_pin]==0                        
          if 5_000_000<(||(cnt-tmp))         
            quit                                                
        stop_time:=cnt                                        
        
        if stop_time>start_time                                
          elapsed_time:=stop_time - start_time
        else
          elapsed_time:=(POSX - start_time)+(POSX + stop_time)               
                                                                                                                                                             
        if elapsed_time>3_250_000                                  
          PAL_or_NTSC_value:=0                                'no video signal   
        elseif elapsed_time>3_100_000                          
          PAL_or_NTSC_value:=1                                'is PAL    
        else                                                       
          PAL_or_NTSC_value:=2                                'is NTSC    
    
    

    THANKS EVERYONE !
Sign In or Register to comment.