Starting an infinite loop from another cog

I want to send a command from one cog to another that will start an infinite loop in the second cog. example< I am reading an mcp3208 adc in a cog(2 actually as 1 is running a PASM routine to actually read the adc) I want to send a command from COG 0 to the mcp cog with the address of a buffer where to put the results of continuous reads of the adc. I will use the contents of the buffer in my main cog. IF the mcp cog has something like this:
PUB main(@ibuff)
   Repeat 
       ibuff[1] == average(1)
       ibuff[2] == average(2)
       ...
       ibuf[8] == average(8)
when I call mcp.main will my cog 0 continue to run serving up the contents of ibuff or will it go off and loop forever in the mcp cog?
Jim

Comments

  • You would need to use cognew to start a new cog running the infinite loop. It would look something like this:
    VAR
      long stack[100]
      long buffer[9]
    
    PUB main
      cognew(looper(@buffer), @stack)
      '...
    
    PUB looper(ibuff)
       Repeat 
           ibuff[1] := average(1)
           ibuff[2] := average(2)
           '...
           ibuff[8] := average(8)
    
    PUB average(num)
    
  • Thanks Dave,
    I got my program to compile and all looks ok. I need to finish up analog connections on the hardware and ring out the adc cs,clock, and data pin connections and it is ready for its first test of the adc.
    Jim
  • frank freedmanfrank freedman Posts: 1,783
    edited 2020-12-21 03:30
    If you have written the ADC as a stand alone module and used something like:

    obj
      clk_gen : "clockgen"    ' continuous cycle of MCP3201 ADC read 
    
    
    PUB Init
      clk_gen.start_clk(ccog,@CGEN)    ' start the MCP320x timing signal generator in cogX. Will continue to cycle ADC pins CS*, CLK at a given clock rate.  Allows n ADC chips into n pins of the prop to be clocked synchronously rather than sequentially
      acq_con : "acq_module"              'also background, timing from clock gen, one for each of the MCP3201, Placed ADC value into addx assigned to that ADC ====> these could be a single background process if only one ADC chip is required 
    
    
    Pub Main
    
    Repeat 
      'see if data is ready
      'read ADC Data address
      'do something
      
    

    You can create a background ADC read process that can read the ADC values and store in a hub location and access the values from another routine or cog as long as said cog knows the address. Also maybe use a semaphore to let the cog looking for the ACD data know that the read cycle is completed.

    Your cog0 can start all your background cogs up, and if they are set to continuously repeat i.e. keep reading the ADC, the background cogs will keep running in their loops until the prop is reset or a cogstop is issued to stop them. Pretty sure the FullDuplex serial object runs continuously in a dedicated cog.
  • Duane DegnDuane Degn Posts: 10,405
    edited 2020-12-21 04:13
    Since "ibuff" is the address of the buffer, you need to include the "long" statement.
    VAR
      long stack[100]
      long buffer[9]
    
    PUB main
      cognew(looper(@buffer), @stack)
      '...
    
    PUB looper(ibuff)
       Repeat 
           long[ibuff][1] := average(1)
           long[ibuff][2] := average(2)
           '...
           long[ibuff][8] := average(8)
    
    PUB average(num)
    

    Here's a tiddier version.
    
    CON
    
      INDEX_SIZE = 9
      MAX_INDEX = INDEX_SIZE - 1
    VAR
      long stack[100]
      long buffer[INDEX_SIZE]
    
    PUB main
      cognew(looper(@buffer), @stack)
      '...
    
    PUB looper(ibuff) | localIndex
      repeat 
        repeat localIndex from 0 to MAX_INDEX 'localIndex will start at zero and stop at 8
           long[ibuff][localIndex] := average(localIndex)
       
    
    PUB average(num)
    
  • RS_Jim wrote: »
    when I call mcp.main will my cog 0 continue to run serving up the contents of ibuff or will it go off and loop forever in the mcp cog?

    I'm not sure what your question is. Is the "main" method in your example code in a separate object (file)?

    If you want a running average of some set number of samples, I'm sure we could help you with that.

  • See attached. I haven't used this in a long time, but it did work in a commercial product created by one of my customers. I reads all 8 channels of the MCP3208 in single-ended mode every millisecond. The start() method sets the pins and the address of the array holding the values. Once its started, you can access the array elements as needed.
Sign In or Register to comment.