Shop OBEX P1 Docs P2 Docs Learn Events
Help converting OBEX object to C — Parallax Forums

Help converting OBEX object to C

I am not really a C guy but I am attempting to convert a timer spin object to C. I am stuck on this line of code, spin2cpp cant even do it correctly as it wont run as converted by spin2cpp.

The spin code line is :
okay := cogon := (cog := cognew(updateTimerDown, @tmrStack)) > 0

Any insight is much appreciated!

Comments

  • dgatelydgately Posts: 1,631
    edited 2020-03-27 15:01
    #include <propeller.h>     
    
    unsigned int okay = 0;
    unsigned  int cogon = 0;
    int cog;
    long tmrStack;
    
    int updateTimerDown();
    
    int main (void)
    {   //EDIT                      '&'
        okay = cogon = (cog = cognew(&updateTimerDown, &tmrStack)) > 0;
    
        // okay and cogon will equal 1 (a boolean "true") if the cog was created successfully
        // cog will equal the created cog number
                                       
    }
    // EDIT
    void updateTimerDown(void *par)
    {
    }
    

    dgately
  • I would have written like this:
    #include "simpletools.h"
    
    void updateTimerDown(void*);
    
    
    int ok;
    int cogon;
    int tmStack;
    
    main ()
    {
      tmStack = 40;
    
      ok = cogon = (cog = cog_run(&updateTimerDown, tmStack) > 0;
    
    }
    
    void updateTimerDown(void *par)
    {
      while (1)
      {
        cog code
      }
    }
    

    cogs do not return a value and run continuously.


    Mike
  • It still doesn't work. seems to die after calling timer.Start()

    Here is the code

    timer.cpp
    
    #include "timer_countdown.h"
    #include "simpletools.h"
    
    
    timer_countdown timer;
    
    int main()
    {
          char* time;
          
          print("starting up\n");
          timer.Start();
          print("Object Started\n");
          timer.Set(0,1,5);
          print("Timer Set\n");
          timer.Run();
          while(1)
            time = timer.Showtimer();       
            print (time);
        
    }
    

    timer_countdown.h
    
    #ifndef timer_Plus_countdown_Class_Defined__
    #define timer_Plus_countdown_Class_Defined__
    
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    class timer_countdown {
    public:
      static const int TIX_DLY = 100;
      static const int MAX_STR = 16;
      static const int TMR_TIX = 0;
      static const int TMR_SECS = 1;
      static const int TMR_MINS = 2;
      static const int TMR_HRS = 3;
      static const int TMR_DAYS = 4;
    
      int	Start(void);
      int	Stop(void);
      int	Set(int H, int M, int S);
      int	Reset(void);
      int	Hold(void);
      int	Run(void);
      int	Rdreg(int Reg);
      int	Wrreg(int Reg, int Value);
      char*	Showtimer(void);
    
    private:
      unsigned int	cogon, cog;
      char 	tmrstack[12];
      int	tix, scs, mns, hrs, dys;
      int	running;
      char 	tmrstr[MAX_STR + 1];
      int	Updatetimer(void);
    };
    
    #endif
    

    timer_countdown.cpp
    #include <simpletools.h>
    #include "timer_countdown.h"
    
    int timer_countdown::Start(void)
    {
      int okay;
      Stop();
      Reset();
      okay = cogon = (cog = cognew(Updatetimer(),&tmrstack)) > 0;
      return okay;
    }
    
    int timer_countdown::Stop(void)
    {
      if (cogon > -1) {
        cogstop(cog);
      }
      return 0;
    }
    
    int timer_countdown::Set(int h, int m, int s)
    {
      Hold();
      tix = (dys = 0);
      scs = (abs(s));
      mns = (abs(m));
      hrs = (abs(h));
      return 0;
    }
    
    int timer_countdown::Reset(void)
    {
      Hold();
      tix = (scs = (mns = (hrs = (dys = 0))));
      return 0;
    }
    
    int timer_countdown::Hold(void)
    {
      running = 0;
      return 0;
    }
    
    int timer_countdown::Run(void)
    {
      running = -1;
      return 0;
    }
    
    int timer_countdown::Rdreg(int reg)
    {
      int result = 0;
      if (reg == TMR_TIX) {
        result = tix;
      } else if (reg == TMR_SECS) {
        result = scs;
      } else if (reg == TMR_MINS) {
        result = mns;
      } else if (reg == TMR_HRS) {
        result = hrs;
      } else if (reg == TMR_DAYS) {
        result = dys;
      }
      return result;
    }
    
    int timer_countdown::Wrreg(int reg, int value)
    {
      if (reg == TMR_TIX) {
        tix = ((abs(value)) % 100);
      } else if (reg == TMR_SECS) {
        scs = ((abs(value)) % 60);
      } else if (reg == TMR_MINS) {
        mns = ((abs(value)) % 60);
      } else if (reg == TMR_HRS) {
        scs = ((abs(value)) % 24);
      } else if (reg == TMR_DAYS) {
        dys = (abs(value));
      }
      return 0;
    }
    
    char* timer_countdown::Showtimer(void)
    {
      int	t, s, m, h;
      t = tix;
      s = scs;
      m = mns;
      h = hrs;
      
      memset( (void *)&tmrstr, 0, 1*((MAX_STR + 1)));
      tmrstr[0] = ((h / 10) + '0');
      tmrstr[1] = ((h % 10) + '0');
      tmrstr[2] = ':';
      tmrstr[3] = ((m / 10) + '0');
      tmrstr[4] = ((m % 10) + '0');
      tmrstr[5] = ':';
      tmrstr[6] = ((s / 10) + '0');
      tmrstr[7] = ((s % 10) + '0');
      tmrstr[8] = '.';
      tmrstr[9] = ((t / 10) + '0');
      tmrstr[10] = ((t % 10) + '0');
      return tmrstr;
    }
    
    
    int timer_countdown::Updatetimer(void)
    {
      tix = 99;
      while (1) {
        if (running) {
          waitcnt(((CLKFREQ / TIX_DLY) + CNT));
          tix = (--tix);
          if (tix == 0) {
            tix = 100;
            (scs--);
            if ((scs == 0) && (mns > 0)) {
              scs = 60;
              (mns--);
              if ((mns == 0) && (hrs > 0)) {
                mns = 59;
                (hrs--);
                if (hrs == 0) {
                  (dys--);
                }
              }
            }
            if ((scs == 0) && (mns == 0)) {
              Reset();
            }
          }
        }
      }
      return 0;
    }
    
  • What does timer.Start(); return? Your code doesn't look at the returned value... And, as lseries stated, you probably need the address '&' of Updatetimer(), (which I had missed initially in my comment):
    okay = cogon = (cog = cognew(&Updatetimer(),&tmrstack)) > 0;
    
  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2020-03-27 15:27
    I tried that, compile fails

    timer_countdown.cpp:9:25: error: lvalue required as unary '&' operand

    timer.start() does not return. It appears to lock up when called.

  • I converted it from C++ to just straight C. Seems to compile and run now, but not getting the right output.
  • char tmrstack[12]; <- this is probably too small, maybe try a little more stack (64 or 128 bytes)
  • All compiles clean now but timer wont run. same value set always diplays

    timer.c
    /*
      Blank Simple Project.c
      http://learn.parallax.com/propeller-c-tutorials 
    */
    
    #include "simpletools.h"                      // Include simple tools
    #include "timer_countdown.h"
    
    int main()                                    // Main function
    {
      // Add startup code here.
      char* time;
          
      countdown_start();
      countdown_set(0,1,5);
      countdown_run();
     
      while(1)
      {
        // Add main loop code here.
        time = countdown_showtimer();       
        print (time);
        print("\n");
        waitcnt(((CLKFREQ / TIX_DLY) + CNT));
        
        
      }  
    }
    
    

    timer_countdown.h
    #include "simpletools.h"
    
      static const int TIX_DLY = 100;
      static const int MAX_STR = 16;
      
      static const int TMR_TIX = 0;
      static const int TMR_SECS = 1;
      static const int TMR_MINS = 2;
      static const int TMR_HRS = 3;
      static const int TMR_DAYS = 4;
    
      int	 countdown_start(void);
      int	 countdown_stop(void);
      int	 countdown_set(int h, int m, int s);
      int	 countdown_reset(void);
      int	 countdown_hold(void);
      int	 countdown_run(void);
      int	 countdown_rdreg(int Reg);
      int	 countdown_wrreg(int Reg, int Value);
      char*	 countdown_showtimer(void);
    
      unsigned int	cogon, cog;
      long 	tmrstack[64];
      int	tix, scs, mns, hrs, dys;
      long	running;
      char tmrstr[17];
      void	countdown_updatetimer(void*);
    
    
    
    

    timer_countdown.c
    #include "timer_countdown.h"
    #include "simpletools.h"
    
    int countdown_start(void)
    {
      int okay;
      countdown_stop();
      countdown_reset();
      okay = cogon = (cog = cognew(&countdown_updatetimer, tmrstack)) > 0;
      return okay;
    }
    
    int countdown_stop(void)
    {
      if (cogon > -1) {
        cogstop(cog);
      }
      return 0;
    }
    
    int countdown_set(int h, int m, int s)
    {
      countdown_hold();
      tix = (dys = 0);
      scs = (abs(s));
      mns = (abs(m));
      hrs = (abs(h));
      return 0;
    }
    
    int countdown_reset(void)
    {
      countdown_hold();
      tix = (scs = (mns = (hrs = (dys = 0))));
      return 0;
    }
    
    int countdown_hold(void)
    {
      running = 0;
      return 0;
    }
    
    int countdown_run(void)
    {
      running = -1;
      return 0;
    }
    
    int countdown_rdreg(int reg)
    {
      int result = 0;
      if (reg == TMR_TIX) {
        result = tix;
      } else if (reg == TMR_SECS) {
        result = scs;
      } else if (reg == TMR_MINS) {
        result = mns;
      } else if (reg == TMR_HRS) {
        result = hrs;
      } else if (reg == TMR_DAYS) {
        result = dys;
      }
      return result;
    }
    
    int countdown_wrreg(int reg, int value)
    {
      if (reg == TMR_TIX) {
        tix = ((abs(value)) % 100);
      } else if (reg == TMR_SECS) {
        scs = ((abs(value)) % 60);
      } else if (reg == TMR_MINS) {
        mns = ((abs(value)) % 60);
      } else if (reg == TMR_HRS) {
        scs = ((abs(value)) % 24);
      } else if (reg == TMR_DAYS) {
        dys = (abs(value));
      }
      return 0;
    }
    
    char* countdown_showtimer(void)
    {
      int	t, s, m, h;
      t = tix;
      s = scs;
      m = mns;
      h = hrs;
      
      memset(&tmrstr, 0, 1*((MAX_STR + 1)));
      tmrstr[0] = ((h / 10) + '0');
      tmrstr[1] = ((h % 10) + '0');
      tmrstr[2] = ':';
      tmrstr[3] = ((m / 10) + '0');
      tmrstr[4] = ((m % 10) + '0');
      tmrstr[5] = ':';
      tmrstr[6] = ((s / 10) + '0');
      tmrstr[7] = ((s % 10) + '0');
      tmrstr[8] = '.';
      tmrstr[9] = ((t / 10) + '0');
      tmrstr[10] = ((t % 10) + '0');
      return &tmrstr;
    }
    
    
    void countdown_updatetimer(void *par)
    {
      tix = 99;
      while (1) {
        if (running) {
          waitcnt(((CLKFREQ / TIX_DLY) + CNT));
          tix = (--tix);
          if (tix == 0) {
            tix = 100;
            (scs--);
            if ((scs == 0) && (mns > 0)) {
              scs = 60;
              (mns--);
              if ((mns == 0) && (hrs > 0)) {
                mns = 59;
                (hrs--);
                if (hrs == 0) {
                  (dys--);
                }
              }
            }
            if ((scs == 0) && (mns == 0)) {
              countdown_reset();
            }
          }
        }
      }
    }
    
    
  • maybe you need to make time a volatile?

    Mike
  • I don't think time variable is the issue. I think it may be the running variable. Not sure how to get the value from the cog. print doesn't work from within the cog.

  • well not a C guy either, but I have read that hub variables used as Mailbox between COG's need to be declared volatile or the GCC compiler will optimize them out.

    Enjoy!

    Mike

  • iseriesiseries Posts: 1,496
    edited 2020-03-27 21:26
    The problem is the cognew function is for assembly programs

    Change it to the following:
      int *c = cog_run(&countdown_updatetimer, 64);
      okay = cogon = (cog = cog_num(c)) > 0; //cognew(&countdown_updatetimer, tmrstack)) > 0;
    

    You can use print function in a cog because it violates the pin rule but you can set pins high and low to see where it is.

    also the function pause(1000) can be used to delay 1 second.

    Mike

    One more thing your returning a point that is already a pointer...
      tmrstr[8] = '.';
      tmrstr[9] = ((t / 10) + '0');
      tmrstr[10] = ((t % 10) + '0');
      return &tmrstr; <-- change this to return tmrstr;  // arrays are already pointers.
    
  • That did the trick!

    Thanks
Sign In or Register to comment.