Shop OBEX P1 Docs P2 Docs Learn Events
Sending data to PST from 2 cogs - - aaaarrrgggghhhh — Parallax Forums

Sending data to PST from 2 cogs - - aaaarrrgggghhhh

homosapienhomosapien Posts: 147
edited 2014-07-02 05:33 in Propeller 1
I have a feeling I am making this harder than it needs to be - I have a program that is running two objects on two cogs. I would like to send data to the Parallax Serial Terminal from both of the running cogs (at different times) to help with debugging.

- I have tried having each cog that wants to write data include PST in the OBJ section, start the PST, and then call PST methods. This works until the second cog starts its PST, then the PST writes stop working (no data seen, from either cog).

- I then tried including PST in the OBJ section of each object, and only calling the start method from one cog. When this is done, only the data from the cog/object that started the PST is seen, the other cogs calls to pst.str() are never seen.

Before I go cooking up some really complicated system for getting data to PST from several cogs, can anyone tell me why one of the above methods do not work? I have boiled the test program down to a pretty simple template with delays, so I am sure that the 2 cogs are not writing at the same time (and causing collisions on the TxRx pins.) I appears that PST simply runs an ASM engine, and the method calls simply load the variables that the ASM engines uses as buffers. Is there a way to get different cogs to load these buffers? As I said, i'm am probably overlooking something pretty simple...


Thanks,
Nate

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2014-07-01 10:04
    The PST object uses VAR variables. If you call the PST methods from different objects you will be using different sets of variables. Make a local copy of the PST object, and change the VAR variables to DAT variables. This way you can call it from any object.

    Now calling the PST methods from different cogs requires that the two cogs don't step on each other. If you know that the two cogs will never call the PST methods at the same time then everything should work OK. Otherwise, you will need to use a lock to ensure that they don't step on each other.
  • homosapienhomosapien Posts: 147
    edited 2014-07-01 10:45
    Hi Dave, Thanks for the response. I was reading the section of the prop manual trying to figure out how the number of included sections (VAR, DAT, etc) would affect this case but was not getting the connection. Thanks for the solution. Just for my knowledge:

    In the first instance, after I called pst.start from each cog, it was really trying to set the tx/rx pins from 2 cogs and getting hung up in the OR'ing of the output pins?

    And in the second instance, when I included 2 copies and only called start from one cog, I would only see data from that cog because calls from the other cog were going to variables that were never seen by the ASM engine?


    Thanks.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-07-01 11:14
    The idle state for the TX pin is logic high. If you start two instances of PST the idle state of one gets ORed with the state of the other, resulting in a net idle state and no transmission. If you can attach a pullup resistor to P30, you can start PST with its StartRxTx method and specify open-drain mode. That will eliminate the ORing problem and allow both instances to transmit, as long as it's done at different times.

    -Phil
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-07-01 11:52
    This is an object I occasionally use when debugging. It uses locks to keep cogs from using the driver at the same time.

    There are almost three times as many methods in this object than most serial objects since there are three versions of many methods.

    For example, the "str" method also has a "strs" and a "stre". The "s" and "e" postfix is to set or clear a lock. You use the "s" version when starting a transmission from a cog and use the "e" version to finish the transmission. There are also "se" methods which will both set a lock and clear it.

    When a lock is set it also identifies the cog doing the talking.

    All "s" methods call the "DebugCog" method and all "e" methods call the "E" method (or they might just clear the lock inline, I don't recall right now).
    PUB DebugCog'' display cog ID at the beginning of debug statements
    
    
      repeat until not lockset(debugLock)
      tx(13)
      dec(cogid)
      tx(":")
      tx(32)
      
    PUB E
    
    
      lockclr(debugLock) 
    
    
    

    The "E" method can be used alone to clear the lock.

    I haven't posted it before because it's so sloppy but it sounds like it could be useful in this case.

    In general it's a good idea to have a single cog in charge of serial communication. I only use this object when debugging stubborn code (I kind I tend to write).

    The buffers are in the DAT section so you can use this in multiple objects but just call "Start" from a single object.
  • edited 2014-07-01 13:08
    homosapien wrote: »
    I have a feeling I am making this harder than it needs to be - I have a program that is running two objects on two cogs. I would like to send data to the Parallax Serial Terminal from both of the running cogs (at different times) to help with debugging.

    Have each cog write data to hub ram and then have PST display that data? The writes could be actual data or symbols to indicate an activity.

    Sandy
  • ElectrodudeElectrodude Posts: 1,658
    edited 2014-07-01 16:01
    MultiCogSerialDebug does exactly what you want. It prints cog id's before each message, and uses locks to make sure multiple cogs don't write at the same time. While the interface is mostly different from that of PST, it has something resembling C's printf (which it calls cprintf), which is nice. You can use Parallax-Serial-Terminal.exe without Parallax Serial Terminal.spin.

    electrodude
  • homosapienhomosapien Posts: 147
    edited 2014-07-02 03:10
    Thank you all for your great responses. I have modified the VARs in PST and added locks to a few key methods (str, dec, hex) to make it work for my particular (hopefully short-term) debugging issue.

    I did do a search for 'PST with 2 cogs' and variations thereof, and found nothing really helpful, I was surprised that it appeared that this was not a more common need. (But the existence of MultiCogSerialDebug and other not-so-easily-findable solutions indicate otherwise).



    Is there any sort of resource similar to Stack Overflow for the Propeller? I find for Java and Android questions the Stack Overflow model is ideal - They save good questions and answers (good as defined by user votes), and is easily searchable so one can find answers to common questions without asking the same questions over and over (and saves more experienced users from answering the same basic questions over and over...)
  • Heater.Heater. Posts: 21,230
    edited 2014-07-02 03:31
    homosapien,
    Is there any sort of resource similar to Stack Overflow for the Propeller?
    Yes, Stack Overflow :)

    I don't see why one can't post Propeller/Spin related questions to SO. Of course nobody much is out there to answer. Unless perhaps you mirror the question here as well. Then all the forum members here would have to sign up to SO as well....arghh...

    OK, what about this forum? Unlike SO questions and answers are not managed in anyway and it's impossible to find anything but people seem to get a lot of mileage out of posting questions here.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-07-02 05:33
    homosapien wrote: »

    I did do a search for 'PST with 2 cogs' and variations thereof, and found nothing really helpful, I was surprised that it appeared that this was not a more common need. (But the existence of MultiCogSerialDebug and other not-so-easily-findable solutions indicate otherwise).

    Weren't you being too specific in saying PST when any terminal etc could be used, it really is a problem with sending serial from two or more cogs on the same pin. This of course can be fixed by making sure that no cog leaves the pin set high but in this case it needs to release it plus you need a pullup on the pin to keep it high = idle.
Sign In or Register to comment.