Shop OBEX P1 Docs P2 Docs Learn Events
Catalina Cog function Help — Parallax Forums

Catalina Cog function Help

AndrePAndreP Posts: 5
edited 2012-09-23 00:22 in Propeller 1
Hello all,
I’m new here and I am also semi-new to the Propeller. So nice to meet you all! Anyways, I have run into a major issue concerning programs compiled from the Catalina C Compiler:
For some reason, my _cogin_C() function appears to run as a regular function (that is, the function runs in line with the rest of the program as any another function would), and whenever that function reaches the end of its execution, the Propeller reboots. The same issue persists even when I attempt to run the demo “multiple_cogs.c” provided with Catalina.
// start instances of ping_function until there are no cogs left
   do {
         // added (delay the program enough so that I have enough time to enable the serial monitor)
         WAIT(20000000*3); 
        
      cog = _coginit_C(&ping_function, &stacks[STACK_SIZE*(++i)]);
 
         // does it get this far?
         cogsafe_print(cog, "Did the program get this far?\n");
   } while (cog >= 0);
When I run the program on my Propeller with the above modifications, the only message that appears in the Serial Terminal window is “Cog 4 started!” If I comment out the while loop in the definition of ping_function(), the Propeller chip reboots. Seeing as the message "Did the program get this far" never appears on the Serial Terminal, I have concluded the _coginit_C() function is not working as it should. Also, it might be worth noting my _clkfreq() always returns 0, but I’ve been circumventing the problem by defining the frequency myself. I’m using a custom configuration setup which is the configuration given on page 17 of the Web-PropellerManual-v1.2 manual and I have the CUSTOM_DEF.INC file configured to match my clock of 20 MHz. I’m at loss as to what my problem might be, so any kind of advice or possible answer to my issue would greatly by appreciated!!

And it’s nice to meet you all, again
AndreP

Comments

  • ul5255ul5255 Posts: 14
    edited 2012-09-15 04:07
    I am not familiar with Catalina C but your mentioning of 20MHz clock triggered some of my own memories. Are you by chance running the Propeller on a 20MHz crystal (let's say with PLLx4)?

    I did this when I started with the propeller as it was a crystal I had around from my Atmel ATTiny experiments. I didnt read the Prop data sheet carefully: A 20MHz crystal is out of spec! My propeller started up but ran unstable, frequency generation with the cog PLLs was 25% off and I couldn't get the serial terminal running. After much head scratching I found the entry in the data sheet, ordered 5.12MHz crystals and all is fine now.

    Again, probably not related to your issue but maybe worth a check.

    Cheers, ul5255.
  • Heater.Heater. Posts: 21,230
    edited 2012-09-15 04:21
    No idea what is going on there but my approach, given I don't have any Catalina manuals to hand, would be some experimental programming.
    Remove the loop and write the equivalent coginit statments in sequence. Add one at a time until it fails.
  • AndrePAndreP Posts: 5
    edited 2012-09-15 09:21
    @ul5244: That is precisely what happened to me when I first started using the Propeller. I didn't realize the PLL mode is not intended to be used with crystals over 5MHz. I thought any crystal was fine so long as the system frequency capped at 80MHz. I later found out my frequency was 25% off, too.

    @Heater.: It always failed after the first one, but I managed to figure out my own issue (and by figure out, I mean I got seriously lucky)...

    #include "propeller.h"#include "stdio.h"
    #include "../Misc/BitManipulation.h"// contains the macros Pin_returnSTATE, Pin_setHIGH, Pin_setLOW
    #define Pin_LED 0
    #define Pin_LED2 2
    #define Pin_BUTTON 1
    
    
    #define stack_SIZE 100
    #define stack_TOTAL 1
    static unsigned long stack[stack_SIZE*stack_TOTAL];
    
    
    void cog(void);
    void pressAndRelease(void);
    void toggleLED(void);
    
    
    int main()
    {
    	// create a pointer that points to the location where the clock is supposed to be stored
    	unsigned long* clock = 0x0000;
    
    
    	// manually set that to the clock frequency
    	*clock = Clock_FREQUENCY;
    
    
    	// wait three sconds so that I can open up the terminal window
    	WAIT(Clock_FREQUENCY*3);
    
    
    	// print out the frequency to terminal
    	printf("frequency %u", *clock);
    
    
    	// Set the directions of the LED pin
    	Pin_setHIGH(DIRA, Pin_LED);
    
    
    	// Set the first LED pin high
    	Pin_setHIGH(OUTA, Pin_LED);
    
    
    	// wait until user presses and releases push button
    	pressAndRelease();
    
    
    	// run function on different cog (the function simply turns the second LED on for three seconds)
    	_coginit_C(&cog, &stack[stack_SIZE]);
    
    
    	// toggle LED (the user should still be able to do this while the cog function is running,
    	// since the cog function should now be running on a separate cog
    	toggleLED();
    
    
    	while (TRUE)
    		continue;
    	return 0;
    }
    
    
    // Prevents the program from proceeding until the push button is pressed then released
    void pressAndRelease(void)
    {
    	Pin_setLOW(DIRA, Pin_BUTTON);
    	while (!Pin_returnSTATE(INA, Pin_BUTTON))
    		WAIT(Clock_FREQUENCY/100);	// wait 1 hundrendth of second for debouncing purposes
    	while (Pin_returnSTATE(INA, Pin_BUTTON))
    		WAIT(Clock_FREQUENCY/100);	// wait 1 hundrendth of second for debouncing purposes
    }
    
    
    // simply turns the second LED on for 3 seconds, and then shutdown the cog
    void cog(void)
    {
    	// set direction of second LED pin
    	Pin_setHIGH(DIRA, Pin_LED2);
    
    
    	// turn the second LED pin high
    	Pin_setHIGH(OUTA, Pin_LED2);
    
    
    	// wait three seconds
    	WAIT(Clock_FREQUENCY*3);
    
    
    	// turn off second LED pin
    	Pin_setLOW(OUTA, Pin_LED2);
    
    
    	// safely end cog
    	_cogstop(_cogid());
    }
    
    
    // toggles LED
    void toggleLED(void)
    {
    	Pin_setHIGH(DIRA, Pin_LED);
    	while (TRUE)
    	{
    		pressAndRelease();
    		if (Pin_returnSTATE(OUTA, Pin_LED))
    		{Pin_setLOW(OUTA, Pin_LED);}
    		else
    		{Pin_setHIGH(OUTA, Pin_LED);}
    	}
    }
    

    I wrote a separate program because I didn't want to mess with the multiple_cogs example any more. But basically, the fact that the _clockfreq() wasn't returning the frequency was actually a big issue. After manually checking the clock frequency using a pointer that pointed to the clock's location in the main memory, I learned the clock's frequency wasn't being saved for reasons I still don't know. In the beginning of the this program, I manually changed the clock frequency in memory with a pointer. Not only does the _clockfreq() function works now, but the _coginit_C() works as well. I managed to fix the rebooting issue by simply telling the cog to stop itself with the _cogstop() function. I'm guessing the Propeller chip is supposed to reboot if a cog finishes the execution of its code, but I couldn't find anywhere in the Catalina reference or the Web-PropellerManual-v1.2 manuals that say that.

    Problem solved for now, I guess. Thanks everyone (Heater and ut5255, mainly) for the assistance!
  • Heater.Heater. Posts: 21,230
    edited 2012-09-15 16:16
    AndreP,
    I'm guessing the Propeller chip is supposed to reboot if a cog finishes the execution of its code,

    No. If a cog is running PASM it has no way to know that it has finished your code. If you do not have a loop it will run off the end of the instructions you have written, continue to execute whatever random junk is in the COG memory and when it gets to the end of memory wrap around and start executing fron zero again.

    If you started a COG running Spin code that does not have an endless loop then the interpreter will execute you spin codes until the end of the function and then stop the COG. The rest of the machine continues as normal.
  • AndrePAndreP Posts: 5
    edited 2012-09-16 05:07
    No. If a cog is running PASM it has no way to know that it has finished your code. If you do not have a loop it will run off the end of the instructions you have written, continue to execute whatever random junk is in the COG memory and when it gets to the end of memory wrap around and start executing fron zero again

    @Heater: Do you have any idea why my Propeller decides to reboot, then? My original problem was fixed after manually inserting the frequency where it needs to be in main memory (though, the fact that I have to do so is another issue in itself). Might my rebooting issue have something to do with my frequency issue?
  • RossHRossH Posts: 5,510
    edited 2012-09-23 00:22
    Hi AndreP,

    Sorry not to notice this thread before. Have you sorted out your problem? If not, please post the entire program and I will have a look. The "muliple_cogs.c" program works ok for me on all my platforms (Hydra, C3, Hybrid, TriBladeProp, RamBlade etc).

    Possibly you have a problem with your platform configuration. What propeller board are you using, and what version of Catalina are you using? By the way, I have just posted version 3.8 - if you are using the 3.7 beta you may want to upgrade - the beta version had a few issues.

    Ross.
Sign In or Register to comment.