Shop OBEX P1 Docs P2 Docs Learn Events
Elementary ICC 'C' program — Parallax Forums

Elementary ICC 'C' program

RsadeikaRsadeika Posts: 3,837
edited 2010-02-18 21:45 in Propeller 1
I downloaded the trial version of ICC, and after looking at there examples, I thought
that I would create a simple turn on an LED, and turn off the LED. This is a good learning
process, and for the people that are thinking about learning 'C', this could be a very
elementary introduction.

As you can see, you have to know some of the Propeller commands, and how they
function. The program below, using the demo board, turns on the LED, which is connected
to pin 16, and then turns it off. This is the equivalent of 'Hello, world', that you would find
in any elementary 'C' book.

The next thing I am going to try is the use of prototype functions. I will keep it very simple,
and straight forward.


//test1.c

// This is the header file that contains
// all of the propeller related commands
// like DIRA, OUTA ...
#include <propeller.h>

// Every 'C' program has to have
// a main function.
void main()
{
// This is for use with the demo board.
// This turns on pin 16 (LED), pauses for a second
// and then turns off the pin.
   DIRA = 1 << 16; // This sets up the pin
   OUTA = DIRA;    // This turns on the pin.
   msleep(1000);   // Make it pause for a second.
   OUTA ^= DIRA;   // This turns off the pin.
}


«13

Comments

  • RossHRossH Posts: 5,519
    edited 2010-02-09 00:44
    Hi Rsadeika,

    This is a good idea. Would you like me to post Catalina equivalents, or would you prefer to keep this thread ICC specific? No problem either way.

    A couple of minor points - when teaching C to newcomers it's probably best to either stay with the ANSI standard (which does not define msleep) or use an equivalent that would be familiar to most existing users (in this case WAITCNT). Also, you could put the pin number in a #define statement to make it easier to adapt the program to other Prop platforms (e.g. the Hydra has a LED on pin 1, not pin 16).

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • RossHRossH Posts: 5,519
    edited 2010-02-09 07:52
    Jazzed said...
    Hmm strange complaint [noparse]:)[/noparse] ... now what was the Catalina ANSI standard printf function name?
    That would be ... let me see ... um ... printf smile.gif

    If you're talking about the Catalina t_printf function, I deliberately called it that so as NOT to confuse it with the standard C printf. You can use either.

    And I don't know how ICC does WAITCNT - my comment was not about Catalina vs ICC - it was that any implementation of WAITCNT would be more familiar to Prop users than msleep.


    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-09 11:47
    I would like to keep this thread ICC specific, and clean of any pis**ng contests. First off, I am not a shill, I just want to evaluate the ICC package for its intended purpose, within the forty five day limit. And, yes, I would like some feed back from the experts, I am sure that some of my examples will have some glaring mistakes. Since this was a spur of the moment idea, I have no idea as to how far I am going to take this. Maybe a few days from now I will decide that 'C' does not really meet my needs at all, and will just give up.

    Maybe another thing to note, their is a learning curve, you have to put the time in to get acquainted with the Propeller commands. In the test1.c program you have to know a little something about DIRA, OUTA, ^=, and there will be others. I think it would be beneficial for one of the experts to weigh in on, how does the '^=' turn off the LED? The whole purpose of this thread is evaluate, get a reasonable feel for embedded 'C', and not to teach 'C'. I thought that the best approach is to start in the simplest manner possible, and in this case, turn on/off an LED.

    Ray
  • RossHRossH Posts: 5,519
    edited 2010-02-09 12:07
    Rsadeika,

    No worries. Anything that encourages more C users to try the Prop has got to be a good thing.

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-09 13:51
    As you look at test1.c code, what is missing? The thing that is missing, or subtly hidden, is:
    _CLKMODE = XTAL1 + PLL16X
    _XINFREQ = 5_000_000

    This issue has come up in another language that is being BETA tested, and it should apply here also. How do you set the freq within an ICC 'C' program? I noticed that in the propeller.h header file there is an include of the propclock.h header file, which has clock definitions, but how do you use it within a program? Hopefully some official example will be provided, so there is no guessing on the users part. For now, just assume, that some magic is occurring.

    The reason I used msleep() function, in the test1.c program, is, that it is there. I would suggest that a read of the 'WAITCNT' command be the next thing to do. In this simple example, the msleep() function, is an appropriate substitute. I remember when I was doing Spin, my response was, all that just to get the program to pause. I guess there has to be some questions answered, in the near future, to make sure everybody is on the right tract.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2010-02-09 14:19
    Rsadeika said...
    I would like to keep this thread ICC specific, and clean of any pis**ng contests.
    No pis**ng intended. Right Ross?
    Function msleep is part of the ICC propeller package just like t_printf is part of Catalina. The propeller.h header provides most Propeller specific code for ICC.

    Setting the clock parameters is done in the ICC IDE. When evaluating ICC the first time, I too noticed this problem and Richard provided his solution. There is a command line equivalent. Read the help doc on ImageCraft's website.

    Post Edited (jazzed) : 2/9/2010 3:03:52 PM GMT
  • RossHRossH Posts: 5,519
    edited 2010-02-09 20:43
    Jazzed,

    Correct.

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • hover1hover1 Posts: 1,929
    edited 2010-02-09 22:06
    This is where you do it.·Project > Options >Target
    Jim
    jazzed said...Setting the clock parameters is done in the ICC IDE.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-09 22:54
    I got my answer for the handling of the clock parameters. I keep forgetting that the professional IDE's have provisions for setting those types of things in the IDE, when you first setup your project.

    After looking at test1.c program I kept thinking, what can I do next. I decided that since I worked with pbasic, it would be nice if I used some familiar commands for turning the LED(s) on/off. So, I went with 'high', 'low', and 'pause' commands (functions). The program below uses some newly created functions, and the use of local variables, as opposed to global variables. Some of the new things are commented, the old stuff is not. The program below is essentially the same as test1.c in functionality, but I think that the 'main()' makes a little more sense, at least from what I am used to. I got rid of '^=', which is basically a toggle, as I understand it, and now it makes a simpler application.

    I hope that some of earlier posters that were inquiring about 'C', make there way to this thread, and maybe they can make a better decision as to their interest in 'C', if it is still there.

    Ray


    // test2.c
    // This illustrates the use of function prototypes
    // to create the 'high', 'low', and 'pause' functions.
    
    // This header file contains the propeller
    // related functions.
    #include <propeller.h>
    
    
    // Some function prototypes, can be located here
    // or after the 'main()' function.
    
    // This sets up the pin, and turns it on.
    void high (int a)
    {
      <edit: This works for the specific pin
                but leaves all the other pins in a 
                float state. Fixed in the next example. edit>
        DIRA = 1 << a;  // 'a' is a local variable.
        OUTA = DIRA;
    }
    
    // This sets up the pin, and turns it off.
    void low (int a)
    {
      <edit: This works for the specific pin
                but leaves all the other pins in a 
                float state. Fixed in the next example. edit>
        DIRA = 1 >> a;
        OUTA = DIRA;
    }
    
    // Just made it so it is called pause. 
    void pause (int a)
    {
        msleep(a);
    }
    
    // In 'C' you have to have a main function.
    void main()
    {
        high(16);
        pause(1000);  // Pauses for one second.
        low(16);
    }
    
    

    Post Edited (Rsadeika) : 2/10/2010 12:59:34 PM GMT
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-02-10 00:10
    I think high() has a problem in that if you already have some pins high, they will be turned off with a new high() instruction; this certainly doesn't match the user's expectations. You have a similar problem with low(). I sincerely believe that high and low should be coded thusly:

    // This sets up the pin, and turns it on.
    void high (int a)
    {
        DIRA |= (1 << a);  // 'a' is a local variable.
        OUTA |= (1 << a);
    
    // This sets up the pin, and turns it off.
    void low (int a)
    {
        DIRA |= (1 << a); 
        OUTA &= !(1 << a); 
    }
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • jazzedjazzed Posts: 11,803
    edited 2010-02-10 00:32
    JonnyMac said...
    I think high() has a problem in that if you already have some pins high, they will be turned off with a new high() instruction; this certainly doesn't match the user's expectations. You have a similar problem with low().· ...
    Jon is right of course. Also consider the "macros" from the ICC manual.

    http://www.dragonsgate.net/pub/help/iccprop/wwhelp/wwhimpl/js/html/wwhelp.htm

    See contents: C LIBRARY AND THE STARTUP FILE -> Propeller Specific Functions
    Many things are explained there in a friendly, concise way.

    [*]CLR(val, bit) - clears a bit given the bit number in val.
    [*][color=#ffffff]SET[/color](val, bit) - sets a bit given the bit number in val.
    [*]FLIP(val, bit) - toggles a bit given the bit number in val.
    

    The macros merely hide what Jon suggested. One still needs to do OUTA = val; for example.
    Good luck.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-10 11:18
    JonnyMac made a suggestion for some code changes to the functions high(), and low(). Just to make sure I decided to test out the preliminary claim.

    I ran the following code:
    high(16);
    pause(1000);
    high(16);
    The result that I observed was, the LED turned on, and then stayed on. I hope that I interpreted JonnyMac's assertion correctly, about what was supposed to happen. I guess I should of observed the LED turning on, pause for a second, and then turn off.

    Next I ran the following code:
    high(16);
    pause(1000);
    low(16);
    pause(1000);
    low(16);
    The result that I observed was, the LED turned on, paused for a second, turned off, and stayed off. Again, the assertion is, that the last 'low(16);' should of turned the LED on.

    Is there something that I am missing here? For the 'high()' code I am using almost the same code that was shown in the example that ICC has. For the 'low()' code, I changed the use of '^=' to '>>', my interpretation being, a zero effect for the pin. I guess we need a little more discussion about this.

    ray
  • BradCBradC Posts: 2,601
    edited 2010-02-10 11:39
    Rsadeika said...

    Is there something that I am missing here?

    Very probably. How about posting your actual source file so we can _really_ see what is going on ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-10 11:50
    This is in reference to the test2.c program that was shown a couple of posts back. All that I am doing is changing the main() contents with what I just showed in my previous post. I did not change any of the code pertaining to the high(), and low() functions, the original code stays the same.

    Ray
  • BradCBradC Posts: 2,601
    edited 2010-02-10 12:00
    Ahh right.. so what you saw was precisely what the code was going to do.
    high() makes the pin an ouput and makes it high.
    low() makes the pin an input and lets if float.

    How exactly was 2 consecutive lows, or 2 consecutive highs going to change the pin state?

    The point JonnyMac was making is your high() and low() routines completely bollox up the state of all the pins in the cog. If your code is only accessing those pins, and don't mine a low being represented as a high impedance input, the the code is fine.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-10 12:37
    This has been an 'Aha!' moment Thanks to BradC, for providing the complete picture. Thanks also goes to JonnyMac for the new code. Now I have some functions that effect the specific pin that is called in the function, and an explanation as to how it works. I will leave test2.c the way that it is, and make the changes in my next example.


    Ray

    Post Edited (Rsadeika) : 2/10/2010 12:54:21 PM GMT
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-10 20:45
    I need lots of help on this example. I wanted to show an asm example using ICC that turns on the LED, pauses for a second, and then turns it off. The program is very erratic, it lights the LED, sometimes it gets turned off, and sometimes it does not. Two other LEDs also turn on, but they never turn off. I think I see some pin(s) floating going, whatever that may mean. Now, everybody is wondering how I came up with this code, I cheated, I used propBASIC to generate the code.

    Ray


    //test4.c
    
    #include <propeller.h>
    
    
    void main()
    {
        unsigned int temp1;
        
        asm("shl temp1,#16");  // Probably all pins float
        asm("or dira,temp1");
        asm("or outa,temp1");
        asm("mov temp1,cnt");
        msleep(1000);
        asm("shl temp1,#16");
        asm("or dira,temp1");
        asm("andn outa,temp1");
        
    }
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-10 21:26
    Rsadeika said...

    //test4.c
    
    #include <propeller.h>
    
    
    void main()
    {
        unsigned int temp1;
        
        asm("shl temp1,#16");  // Probably all pins float
        asm("or dira,temp1");
        asm("or outa,temp1");
        asm("mov temp1,cnt");
        msleep(1000);
        asm("shl temp1,#16");
        asm("or dira,temp1");
        asm("andn outa,temp1");
        
    }
    
    


    Some problems:
    • temp1 needs to be initialized i.e. "unsigned int temp1 = 1;"
    • temp1 or any C variable in asm(...) needs to have% prepended
    If all you want to do is flip the LED, re-write it as:
    #include <propeller.h>
    
    void main()
    {
      unsigned int temp1 = 1 << 16;
      while(1) {
        asm("or dira,%temp1");
        asm("or outa,%temp1");
        msleep(1000);
        asm("andn outa,%temp1");
      }    
    }
    
    
    


    The mixed assembly approach is best to use where possible for ASM vs the assembler. This does make code less portable between micros though.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-10 23:10
    Thanks jazzed, I am going to let your post be the example for doing assembly in ICC. I think it is simple enough, code wise, to let people get an idea of what it takes to do it in ICC.

    So far I am having a very good experience with the ICC IDE, so, yes I would tell other people to go ahead and use it. As a tool to learn 'C' with, I am starting to think that it is a good choice, although you would need to invest in some books that deal with 'C' at a beginners level. I found my old copy of the 'K&R' 'C' book, so I could refresh, or get rid of some of the cobwebs in my brain, that deal with that subject.

    The examples that were shown here, just barely scratch the surface of what the 'C' language can accomplish. As the title of this thread states, I am trying to keep it as elementary as possible. I also want to mention that you can make the program even less cluttered, for instance, in test2.c you could take the new functions that were created, and put them into an '.h' file. To access the functions you would do an '#include <xxx.h>', and the functions should be available. The reason I mention this, is because you could start creating a 'tool chest' of your favorite functions, and use them in other programs by simply doing the include. For the rest of the examples I will not use this method, I will continue to show the functions. Thinking of functions, maybe what 'C' needs is a 'tool chest' of basic stamp functions, maybe that would get some of the basic stampers interested in 'C'. Just a thought.

    The next example that I am working on will deal with the use of cogs, of course it will be flashing some LEDs, and using the functions that were developed. After I finish with the cog(s) example I need to know what other areas I should cover for a good elementary introduction? I need some ideas. Maybe ICC has a suggestion, or some examples that they have stashed away in an '.h' file.

    Ray
  • RossHRossH Posts: 5,519
    edited 2010-02-10 23:56
    Ray,

    There's loads of good introductory C code and courses on the internet that you could try. ICC is an LCC variant, so provided you stick to ANSI C then it should pretty much just compile and run.

    Or you could use the examples out of K&R itself. I have the second edtion - everything in there should run ok with the possible exception of some of chapter 8 (which is specific to the UNIX file system). Actually, even some of those examples might run if ICC implements UNIX style file system primitives internally.

    The main problem you will run into is that because the Prop is an embedded system it doesn't usually have a command line - so for programs that need one I use a wrapper function instead. I have enclosed an example one which was written for the Pascal P4 interpreter (PCOM). All the wrapper function does is prompt for arguments and then call the program's main() function - as far as the program is concerned it thinks it was invoked from a command line.

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-11 11:00
    Thanks for the insight RossH. I guess I have the first edition of the K&R book, it has "Copyright (c) 1978 by Bell Telephone Laboratories, Incorporated.", on the inside page. It is a very thin book, by comparison, but packed with some very useful, essential information for learning the 'C' language. Has 'C' been around that long!

    For the visitors that are stumbling onto this thread, I am not a professional programmer, some people say that I am not even a programmer in the true sense of the meaning. So, take everything I say with a grain of salt.

    What the heck is ICC? The name of the company is ImageCraft (IC), and they sell an embedded 'C' product. I think that ICC has a nice ring to it. Parallax also sells there product, and I believe that the package deal that they have, a demo board, and the ICC compiler, is a very good deal. I purchased a demo board quite awhile back, so I am missing out on this deal. I hope that Parallax keeps this package deal going, maybe make it a standard package at the existing price.

    Why should I get involved with 'C'? Now this is a tough question to answer, anybody that has been around here for any length of time has seen some of the passionate defense postures of there particular favorite language, or language derivative. My intent here is not to start another 'flame war', but just 'C' if some logic can be applied to, why should I use 'C'. One thing comes to mind, being lazy, if I was not lazy, I would put in the time to learn assembly for the Propeller. Having said that, assembly is not an easily transferable language between computers, in this case processors. That statement alone has potential for a heavy 'flame war'. Now, 'C' has been around for a very long time, it has stood the test of time. 'C' has a kind of sensible structure to it, of course that is my opinion. 'C' can be as simple or as complex as you want to make it, plus you can do some inline assembly, if you must. I really have not answered the question, because I am still undecided as to whether 'C' can be useful for me.

    As I work through some more of these elementary examples, I will probably get closer to that answer. I had mentioned in an earlier post, about barely scratching the surface, I was just looking at the help file for ICC, and I noticed that it has some built in functions for using a VGA monitor, I might have to investigate that a little more. It also has some built in functions for using a serial port. Lets see, demo board, VGA, keyboard, serial port, could I make my demo board run a serial terminal program? Of course the demo board is missing an SD card adapter, so that would limit my idea. But, I will keep that in mind.

    Now, back to finishing up my next example ...

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-11 16:12
    The program below flashes some LED's, it uses a couple cogs, and in the main(), it uses a while(1) function. As I mentioned, I am using the old created functions, and I added a couple of new ones.

    I have some questions about the functions, I still do not understand how you use a function prototype. Here you just type in the function, and it runs. In the help file it mentions the use of function prototypes, but gives no specific example. The way I have seen it done, in other compilers, is, in the beginning of the program you would place 'void high( int );', this is the function prototype, then the function itself, above main, and in some cases, below main().

    The function(s) that I have created all start with 'void', and I have seen some with 'int', I am assuming that the function that starts with the 'int' will be used with a 'return' within the function. Are there any other types that are used with ICC?

    I noticed, in my program below, that when I placed blinker1(), and blinker2() below the main() function, I got a compile error, when I placed the functions above the main(), it compiled, I am not sure why that is happening. Other than that, the program seems to be running as expected. I am still considering this an elementary program, or am I wrong?

    Ray


    //test3.c
    
    #include <propeller.h>
    
    // These three commonly used functions
    // could probably be placed in there
    // own header file.
    void high (int a)
    {
        // This now contains the
        // more efficient code.
        DIRA |= (1 << a);
        OUTA |= (1 << a);
    }
    
    void low (int a)
    {
        // This now contains the
        // more efficient code.
        DIRA |= (1 << a);
        OUTA &= !(1 << a);
    }
    
    void pause (int a)
    {
        msleep(a);
    }
    
    // These cog related fuction(s) have to be 
    // above the 'main()' function.
    
    // This will be in its own cog.
    void blinker1()
    {
        while(1)  // This is a forever call.
        {
            high(16);
            pause(500);
            low(16);
            pause(500);
        }
    }
    
    // This will be in its own cog.
    void blinker2()
    {
        while(1)  // This is a forever call.
        {
            pause(100);
            high(23);
            pause(500);
            low(23);
            pause(500);
        }
    }
    
    // The stack calls have to be in global memory.
    long b1stack[noparse][[/noparse]20];
    long b2stack[noparse][[/noparse]20];
    
    void main()
    {
        cognew(blinker1, &b1stack[noparse][[/noparse]19]);  // Start blinker1.
        cognew(blinker2, &b2stack[noparse][[/noparse]19]);  // Start blinker2.
        
        while(1)  // This is a forever call.
        {
            high(19);
            pause(200);
            low(19);
            pause(200);
        }
    }
    
    
    
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-11 17:08
    Rsadeika said...
    I guess I have the first edition of the K&R book
    ...
    Why should I get involved with 'C'?

    I had a first edition K&R book long ago. It's antique now; wish I kept it.
    Just ordered a used copy from Amazon - only 2 left now.

    Two reasons to get involved with C/C++:

    1. Hobbyist: using micro-controllers where most user code is written in C.
    2. BSCS degree: greater marketability for generating income - maintaining ugly old code [noparse]:)[/noparse]


    Function prototypes can be used in one file as a summary of functions being used when main is defined before the functions main will use ... professors like this [noparse]:)[/noparse]. As you found out, if something is not defined before main there will be errors (in a single .c source file program).

    Function prototypes are also used in header files where the library implementation is provided as an archive and/or in a separate .c file. The reason for this is letting the compiler check the correctness of function calls by user code. This is sort of a missing feature of Spin, but very rarely has it actually cause me trouble, so the extra work might not be worth the effort in Spin.


    You have lots of blinky lights now [noparse]:)[/noparse]

    I challenge you to create "scrolling text" on 8 LEDs. Basically each vertical line of a character is displayed for a time. Connecting an accelerometer would allow you to sweep the display in the air and make the output readable in persistence of vision (output displayed within 50ms).
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-11 20:03
    I am thinking about another example, and I would like to know if ICC has a push(), and pop() function? What header file would that be in? Now, if those two functions do not exist, how could they be coded? I guess this involves the simulation of a stack, if those two functions do not exist. Anybody have any ideas as to what the code would look like?

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2010-02-11 20:42
    Rsadeika said...
    I am thinking about another example, and I would like to know if ICC has a push(), and pop() function
    There is no library push/pop in ICC that I know of.

    For a fixed allocation stack, use single dimension array. A dynamic linked list can be used similarly (code in the OBEX). A tail pointer would of course make it much more efficient for a stack.

    // Untested, but this is the general idea.
    // A less *general* set of functions could use global variables.
    //
    
    //push as "push(&array, &index, dat);"
    void push(int *array, int* index, int dat)
    {
      int ndx = *index;
      array[noparse][[/noparse]++ndx] = dat;
    }
    
    //pop as "dat = pop(&array, &index);
    int pop(int *array, int* index)
    {
      int ndx = *index;
      return array[noparse][[/noparse]ndx--];
    }
    
    // peek as "dat = peek(&array, &index);"
    int peek(int *array, int* index)
    {
      return array[noparse][[/noparse]*index];
    }
    
    // full? "full(&array, &index);"
    int full(int *array, int *index)
    {
      return *index >= sizeof(*array)/sizeof(int) ? 1 : 0;
    }
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-11 22:25
    This example is not working correctly, if somebody could give it a glance, maybe it will be obvious. The problem is, that it is not functioning as an RPN on the terminal screen. When I type in '1 1 + =' there is no result being shown. So, I am not sure if the case statement for '=' is not functioning correctly, or what. I put in an 'esc' trap, that seems to be working, the numbers are being shown as pressed on the keyboard. Also, the '+', '*', '-', '/', are being shown, but no results.

    I think that once I get this thing to work, than I will expand on this theme, maybe add some kind of scheme to light up some LEDs for the corresponding numbers. How could I show, via the LEDs, an addition of 9 9 +? Maybe my own style of abacus? There are only eight LEDs on the demo board to work with.

    This program is an example out of the K&R book, that is why I put in an "homage" in the title. It took a little bit of code manipulation to get this thing to semi-work, but at least it starts up , and shows some stuff on my screen.


    Ray


    // test5.c
    
    #include <stdio.h>
    #include <stdarg.h>
    #include "asio.h"
    
    #define maxop 20
    #define number '0'
    #define toobig '9'
    #define EOF 27
    #define maxval 100
    
    int sp = 0;
    double val[noparse][[/noparse]maxval];
    
    int pop()
    {
        if (sp > 0)
            return(val[noparse][[/noparse]--sp]);
        else {
             printf("error: stack empty\n");
             clear();
             return(0);
        }
    }
    
    int push(double f)
    {
        if (sp < maxval)
            return(val[noparse][[/noparse]sp++] = f);
        else {
             printf("error: stack full\n");
             clear();
             return(0);
        }
    }
    
    
    void clear()
    {
        sp = 0;
    }
    
    
    
    main()
    {
        int a;
        int type;
        char s[noparse][[/noparse]maxop];
        double op2, atof(), pop(), push();
        
        asio_init(57600);  // Connect to an external terminal 57600 BAUD
        
        msleep(5000);  // Need some time to start up terminal program.
        
        puts("Reverse Polish Notation calculator");
        puts("Homage to K&R");
        
        while ((a = getchar()) != EOF)
            type = isalnum(a); //This might be a problem.
            switch (type){
            case number:
                push(atof(s));
                break;
            case '+':
                push(pop() + pop());
                break;
            case '*':
                push(pop() * pop());
                break;
            case '-':
                op2 = pop();
                push(pop() - op2);
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0)
                    push(pop() / op2);
                else
                    printf("zero divisor popped\n");
                break;
            case '=':
                printf("\t%f\n",push(pop()));
                break;
            case 'c':
                clear();
                break;
            case toobig:
                printf("%.20s ... is too long\n", s);
                break;
            default:
                printf("Unknown Command %c\n", type);
                break;
        }
        puts("All Done!");
    }
    
    
    
    
  • RossHRossH Posts: 5,519
    edited 2010-02-11 22:58
    Ray,

    You really should just use the K&R version directly - the version in the second edition should compile and run properly. If you are using a version out of the first (non-ANSI) edition of K&R it may not be ANSI compliant and you may need to make further changes, such as:

    You need to declare clear() as "void clear();" before referring to it.
    The push() and pop() functions should return doubles, not ints.
    Rename EOF as it will conflict with the stdio definition.
    The function isalnum() returns only true or false, not the values you are checking for - the K&R version uses getop() which is defined a couple of pages later.
    Remove all references to "asio"
    Dump the "msleep"

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • jazzedjazzed Posts: 11,803
    edited 2010-02-12 00:13
    RossH said...
    You really should just use the K&R version directly - the version in the second edition should compile and run properly. If you are using a version out of the first (non-ANSI) edition of K&R it may not be ANSI compliant and you may need to make further changes ....
    Owning K&R first edition is more of a novelty. As Ross suggests, ANSI C should be used where possible. Of course at this point we're forced to use the C89 variant until someone makes a C99 tool set available on Propeller·- please hurry heater [noparse]:)[/noparse]

    The asio library is used for serial communications in ICC. Please note that the header is only included so that the init function call can be checked by the compiler for proper use. Other than that, the asio tx/rx routines are encapsulated in the IO functions. While that is the way it works, I suggest using the FdSerial library from the OBEX as there are no timing dependencies in FdSerial as there are in asio the library.

    Function msleep is a valid function call in a similar vein as the WAITCNT macro and other chip specific functions.

    However, making a C program as portable as possible is a very good goal, and there are ways to do it as Ross has started with the Catalina/ICC compatability module in his release thread. In a professional development environment where a company's fortune's are won and lost because of new product line shipment schedules,·additions to a product line, and maintenance (if you have staff for it[noparse]:)[/noparse] this is even more critical. But in that environment, an object oriented·language like C++ (or even a standard C methodology such as using a POSIX compliant operating system with access to kernel modules/services) should be used to promote easy code reuse. Of course using a fully POSIX compliant operating system today for Propeller is not possible (as far as I can tell CP/M does not offer POSIX file compatability ... someone will correct me if I'm wrong here I'm sure). Basically, for an embedded system, you get "alternatives" that not everyone will appreciate. C old timer programmers and the ones fresh out of school are usually a tough bunch to please [noparse]:)[/noparse]

    No pi**ing intended [noparse]:)[/noparse]
  • RossHRossH Posts: 5,519
    edited 2010-02-12 01:11
    Jazzed,

    My mistake - I thought "asio" must be something out of the original vintage 1970's K&R. And I suggested dropping "msleep" only because it is no longer required if you don't need the "asio" module.

    On C99 - even though it is now over 10 years old, C99 is still a bit of a curiosity. It tends to be fully implemented only by the (expensive!) commercial compilers, and not even all of those (see here). The "free" compilers don't tend to bother with C99 because it doesn't add many features over and above C89 for most applications - and the users that wanted those features had mostly already migrated to C++ anyway (and have no doubt regretted it ever since!).

    Even gcc has only partial support for C99, so heater's efforts (I presume you are referring to Zog?) won't necessarily help.

    But C++ on the Prop? I know some lunatic in these forums will eventually write a native C++ compiler for the Prop - but WHY??? freaked.gif

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • jazzedjazzed Posts: 11,803
    edited 2010-02-12 02:13
    Ross, I'm afraid Ray will slap us soon [noparse]:)[/noparse]

    GNU is the primary functional C99 tool available today and for the last 10 years. I'm sure other alternatives are helpful. If you want to compile linux and many of its utilities, you have no choice. Using C89 based tools for compiling linux is not possible. I'm sure some form of Unix or other POSIX compatible OS can be compiled with C89.

    >> But C++ on the Prop?

    I did not suggest C++ is a good fit for Prop, only that it is used in·professional development environments where billions of dollars is at stake. If you start making billions of dollars using Prop by itself, that would be a real kick for all of us. Great problem to have [noparse]:)[/noparse]

    BTW: I personally dislike C++,·but·use it because Java/C# are not fast enough for many solutions other than PC,·and I avoid·Pascal mainly because C and·variants have been my mainstay for 20 years. Interestingly, and probably on purpose for the Delphi fans, SPIN and Pascal are very similar.

    C is also used extensively in the billions of dollars·environment, but as most of the 20+ year old companies who use that model have found (Cisco, etc...), it is very expensive to maintain even with millions of·C programmers because 1: the products have outgrown themselves, 2: most people who know what to do with the language are too expensive to hire, and 3: trying to do it on the cheap just makes matters worse.

    Cheers.
Sign In or Register to comment.