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

Elementary ICC 'C' program

2

Comments

  • BradCBradC Posts: 2,601
    edited 2010-02-12 07:02
    jazzed said...
    Interestingly, and probably on purpose for the Delphi fans, SPIN and Pascal are very similar.

    Yay for me!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    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-12 11:05
    I thought I would take the time, and post the original K&R code. Just a couple of points, I will be referring to this as 'Classic' C. The original book is more than just a novelty, if you want to learn, from the "horses mouth", about how to use the built in functions such as 'switch case', 'if else', and so on, this is the book.

    As expected this does not compile using ICC, my program, was a slightly butchered version of the original, and it did not work as expected. So, now what do I do? Should I take the time to make it work? I think that I will try to make this work, it should be a good learning experience.

    I guess I have to identify what the problem area is.
    1. Function prototypes.
    2. Use the proper I/O procedure for this program.

    Probably more things will show up as I start to modify the program so it runs correctly in a derivative of 'Classic' C.

    Ray


    //ClassicC.c
    
    #define MAXOP  20
    #define NUMBER  '0'
    #define TOOBIG  '9'
    
    main()  /* reverse Polish desk caculator */
    {
        int type;
        char s[noparse][[/noparse]MAXOP];
        double op2, atof(), pop(), push();
        
        while ((type = getop(s, MAXOP)) != EOF)
            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;
            }
    }
    
    #define MAXVAL  100  /* maximum depth of val stack */
    
    int sp = 0;  /* stack pointer */
    double val[noparse][[/noparse]MAXVAL];  /* value stack */
    
    double push(f)  /* push f onto value stack */
    double f;
    {
        if (sp < MAXVAL)
            return(val[noparse][[/noparse]sp++] = f);
        else {
             printf("error: stack full\n");
             clear();
             return(0);
        }
    }
    
    double pop()  /* pop top value from stack */
    {
        if (sp > 0)
            return(val[noparse][[/noparse]--sp]);
        else {
             printf("error: stack empty\n");
             clear();
             return(0);
        }
    }
    
    clear()  /* clear stack */
    {
        sp = 0;
    }
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-12 12:55
    Starting with small proven pieces of code, and build from there. The program below is just a little program that allows you to press a key on the keyboard, and it shows up on the screen of your favorite terminal program. I did find out that if you use anything higher than 9600 BAUD, I start to get garbage characters on the screen. I am not sure if this is a problem with my terminal program, or something else is going on.

    The program works as expected, except for the escape part. It seems that my ' if ' statement is not responding correctly to the 'esc' value, in other words when I hit the 'esc' key, the screen shows '<-', but does not break out of the while loop. I am not sure how to overcome that predicament. All, and any suggestions are welcome.

    Ray


    //test6.c
    
    #include <propeller.h>  // Will need this later.
    #include "asio.h"  // This the terminal I/O.
    
    #define esc 0x27   // Define the 'esc' key.
    
    main()
    {
        msleep(5000); // Need this time to start 
                      // up the terminal program.
        
        asio_init(9600);  // Select the baud rate
        
        puts("Hello, World");    
        
        while (1)   // Forever loop
        {
            
            int a;
            
            a = getchar();
            if ( a == esc ) // End the while loop
               return 0;    // when esc key is pressed.
            putchar(a);     // Otherwise continue.
        }
        
        puts("Good Bye");
    }
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-12 14:21
    Rsadeika said...
    I did find out that if you use anything higher than 9600 BAUD, I start to get garbage characters on the screen. I am not sure if this is a problem with my terminal program, or something else is going on.
    Again, I suggest using FdSerial from the obex instead of asio for serial communications. It is faster and more reliable.
    Rsadeika said...
    The program works as expected, except for the escape part. It seems that my ' if ' statement is not responding correctly to the 'esc' value, in other words when I hit the 'esc' key, the screen shows '<-', but does not break out of the while loop. I am not sure how to overcome that predicament. All, and any suggestions are welcome.
    Change return 0; to break; in your while loop. Always put a while loop at the end of main.

    //test6.c
    
    #include <propeller.h>  // Will need this later.
    #include "asio.h"  // This the terminal I/O.
    
    #define esc 0x27   // Define the 'esc' key.
    
    main()
    {
        msleep(5000); // Need this time to start 
                      // up the terminal program.
        
        asio_init(9600);  // Select the baud rate
        
        puts("Hello, World");    
        
        while (1)   // Forever loop
        {
            
            int a;
            
            a = getchar();
            if ( a == esc ) // End the while loop
               break;    // quit while loop when esc key is pressed.
            putchar(a);     // Otherwise continue.
        }
        
        puts("Good Bye");
    
        while (1);   // Forever loop to keep Propeller doing something sane instead of printing garbage
    }
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-12 16:07
    The program below, now works as expected. Using the case statement, you can turn on/off an LED. Pressing the letter 'p' breaks out of the loop, and ends the main program. Still can not figure out why I can not get the 'esc' key to respond correctly within the program. I also noticed that the compiler does not like stuff like 'while( !=0 )', must be a limitation of the compiler, or maybe I am just using incorrectly.

    Ray


    //test6.c
    
    #include <propeller.h>  // Will need this later.
    #include "asio.h"  // This the terminal I/O.
    
    
    
    void high (int a)
    {
        DIRA |= (1 << a);
        OUTA |= (1 << a);
    }
    
    void low (int a)
    {
        DIRA |= (1 << a);
        OUTA &= !(1 << a);
    }
    
    main()
    {
        msleep(5000); // Need this time to start 
                      // up the terminal program.
        
        asio_init(9600);  // Select the baud rate
        
        puts("Hello, Propeller World");  // The greeting
            
        
        while (1)   // Forever loop
        {        
            int a;
            
            a = getchar();
            switch ( a )
            {
                case '1':
                    high(16);   // Turn on the LED.
                    break;
                case 's':
                    low(16);    // Turn off the LED.
                    break;
                default:
                    break;
            }
            
            if ( a == 0x71 ) // 'q' ends the while loop
                   break;    
            putchar(a);      // Otherwise continue.
        }
        puts(0x10);        // This drops a line but
                           // puts garbage characters
                           // on the screen.
        puts("Good Bye");
    //    while(1);
    }
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-12 16:59
    Rsadeika said...
    The program below, now works as expected. Using the case statement, you can turn on/off an LED. Pressing the letter 'p' breaks out of the loop, and ends the main program. Still can not figure out why I can not get the 'esc' key to respond correctly within the program.
    What terminal are you using? Sometimes a terminal program will try to do you favors [noparse]:)[/noparse]
    Rsadeika said...
    I also noticed that the compiler does not like stuff like 'while( !=0 )', must be a limitation of the compiler, or maybe I am just using incorrectly.
    while( !=0 ) is not a valid statement. while is expecting an valid expression that evaluates to 0 or non-zero. while(1!=0) is valid. while(1) is valid.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-12 18:42
    I am using my own minimalist terminal program which I coded in freeBASIC. It does not contain any code that would help you along. It works very well in other situations, so I do not think that it is my terminal program, I could be wrong though. The only regret that I have with the program is, I did not put in the option to turn off the local echo. In the situation that I am using it now, I have to put up with the double characters on the screen.

    After looking in the K&R book, a few pages down, there was a listing for the 'getop()' function, but that would not of helped in making the program compile. I have to figure out away of getting around the limitations of the ICC 'while'. The K&R example programs uses a lot of 'while ((type = getop(s, MAXOP)) != EOF' stuff, and that just makes the ICC compiler go crazy.

    Ray
  • RossHRossH Posts: 5,519
    edited 2010-02-13 00:02
    Ray said...
    The K&R example programs uses a lot of 'while ((type = getop(s, MAXOP)) != EOF' stuff, and that just makes the ICC compiler go crazy.
    There must be something else causing your problem - this is a perfectly valid statement for ANY C compiler (provided all the symbols and functions are actually defined!).

    In english it would be equivalent to saying "call the 'GETOP' function and assign the result to 'type'. Then compare 'type' to EOF and while they are not equal, do the following ..."

    ICC is close enough to LCC that I am confident it will compile that statement correctly - what is that actual error message you get?

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-13 11:21
    The program below is an almost exact copy of the example that I used from the K&R book, exact, meaning the actual code, and not the added include files. I was impressed with the ICC compiler because the output that is produced contains minus signs (-), and decimal points (.), and the numbers are carried to six places. I could not figure out how to use the 'printf' to limit the scope of the number, meaning if I only wanted two places after the decimal point shown.

    Some things to worry about when using 'C', make sure that you have the semicolons ([noparse];)[/noparse], in the proper places, it compiles, but the expected results are not there, or even worse, there might be just a very subtle change. I was lucky that it made me aware when I was coding the program below, it took me awhile before I realized that I was missing a ';'. I guess it gets even worse if you happen to omit a curly bracket '{}' , in some code that uses a lot of 'while', and 'if' statements.

    I should mention that I am using the project capabilities of the ICC IDE, it keeps a lot of the compiler produced files associated with the project in one place. It was a little awkward when I first started to use it, but it is working out quite nicely.

    So, what is the importance of the program below? First off it did the conversion formula, it outputted the results, which could be manipulated even further than what I did, I hope. I did this via a terminal program, ICC has some VGA functions built in, so you could go that route for display. And you could probably write some code to pass the output to an LCD display connected to the demo, or prop board. And the evaluation continues ...

    Ray


    //test8.c
    
    #include <stdio.h>
    #include <propeller.h>
    #include "asio.h"
    
    
    
    main()
    {
    float fahr, celsius;
    int lower, upper, step;
    
        msleep(5000);    // Wait time
        
        asio_init(9600); // Baud rate
        
        lower = 0;     // lower limit of temperture table
        upper = 300;   // upper limt
        step = 20;     // step size
        
        fahr = lower;
        puts(" Temperture");            // Added this
        puts("Fahrenheit Celsius");   // Added this
        while (fahr <= upper)
        {
            celsius = (5.0/9.0) * (fahr-32.0);
    // The actual K&R code is
    // printf("4.0f %6.1f\n", fahr, celsius);        
            printf("%f         %f\n",fahr,celsius);
            fahr = fahr + step;
        }
    
    }
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-13 21:25
    For the test8.c program, 'printf()' stuff, I figured it out. It is as simple as '%3.2f', which will display a number with three leading digits, and two digits after the decimal point, in float (double) number. I do not know why it did not work for me the first time I used something like that, maybe it's the 'something like that' that will get you. I do not know if anybody is trying this out, but if you use the ICC IDE terminal program, be warned that the output does not come out in two columns. On my terminal program it comes out in two columns.

    I must confess, I downloaded and installed openwatcom 'C' on my computer. It did not take me very long to get a "Hello, World" running, with a terminal like scenario where I can type in some letters, a CR drops down one line, and uses the 'esc' key to close the program. The other thing that I like about openwatcom is, all the manuals can be downloaded, and they are in a .pdf format. So, you do not have to buy any additional books. The manuals all contain pertinent examples that show how to use the command, or whatever it may be describing. The only problem I have with it is that it only creates .exe files, no .bin files.

    So, now I have to think about what my next example will be. Maybe a discussion about how to do pin settings, for instance how do you set a pin for output, input, and whatever else could be possible.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-14 14:19
    The program below has my rendition of input for a pin, and I changed the the names to reflect what is actually occurring. The program compiles, but I have to figure out an easy way of testing the new function, using the demo board. I thought about connecting p7 to p6, put p6 in a high state, and then check p7 for a (1). Something like this:
    int b;
    PinHigh(6); //Set pin high
    b=PinInput(7); // Check for input
    if (b == 1) // Is there some voltage
    {
    PinHigh(16);
    pause(1000);
    PinLow(16);
    }

    Not sure if I am on the right track with this line of thought.

    Ray



    //test9.c
    
    #include <propeller.h>
    
    int PinInput(int a)
    {
        DIRA = (1 << a);  // Direction state.
        INA  = (1 << a);  // Input state.
        return(a);        // Not sure if this is 
                          // necessary. 
    }
    
    void PinHigh(int a)
    {
        DIRA |= (1 << a);  // Direction state.
        OUTA |= (1 << a);  // Output state.
    }
    
    void PinLow(int a)
    {
        DIRA |= (1 << a);  // Direction state.
        OUTA &= !(1 << a); // Output state.
    }
    
    void pause(int a)
    {
        msleep(a);
    }
    
    
    main()
    {
       // Added some code just to
       // see if it compiles.
        int b;  
        b=PinInput(7);  
     
        PinHigh(16);
        pause(1000);
        PinLow(16);
    
    }
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-14 17:03
    I guess there is something wrong with my PinInput() function. I made a little push button circuit on the breadboard, I have the ground side of the push button hooked to p7, the other side of the push button to power, and I have an LED circuit hooked to p6. I tested the push button, it works, and the LED on p6 works. As for the PinInput() function, I figured that you have to set the direction state, which I did, and do the INA setting it to input. Now I am lost, in theory it should work, but in reality it does not. Any help would be appreciated.

    Ray



    //test9.c
    
    #include <propeller.h>
    
    int PinInput(int a)
    {
        DIRA = (1 << a);  // Direction state.
        INA  = (1 << a);  // Input state.
        return(a);        // Not sure if this is 
                          // necessary. 
    }
    
    void PinHigh(int a)
    {
        DIRA |= (1 << a);  // Direction state.
        OUTA |= (1 << a);  // Output state.
    }
    
    void PinLow(int a)
    {
        DIRA |= (1 << a);  // Direction state.
        OUTA &= !(1 << a); // Output state.
    }
    
    void pause(int a)
    {
        msleep(a);
    }
    
    
    main()
    {
       // Added some code just to
       // see if it compiles.
       int b;
       PinHigh(6);  // Just to test the LED.
       pause(1000);
       PinLow(6);
        while(1)
        {
            //int b;  
            b=PinInput(7);
            if (b == 1)  // Is the button pressed
            {  
                PinHigh(6);   // Yes
                pause(250);
                PinLow(6);
                pause(250);
            }
        }
    }
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-14 17:29
    Rsadeika said...
    I guess there is something wrong with my PinInput() function.
    Yes there is. Try this.

    // corrected version
    // assumes int is 32 bits which is not always the case especially with Watcom
    //
    int PinInput(int a)
    {
        DIRA &= ~(1 << a);  // Create mask, invert to clear direction state.
        return (INA  & (1 << a)) ? 1 : 0;  // Return input state as 1 or 0.
    }
    
    // same as above but easier to understand ....
    // assumes int is 32 bits which is not always the case especially with Watcom
    //
    int PinInput(int a)
    {
        int  rc = 0; // some compilers complain if not assigned a value on entry
        int  bitmask = (1 << a); // Create a mask i.e.: 0x10000 = 1 << 16
        int invmask = ~bitmask; // Invert mask i.e.: 0xFFFEFFFF = ~(1 << 16)
        DIRA = DIRA & invmask;  // Clear direction state for input pin.
        rc = INA; // get input
        rc = rc & bitmask; // check only for input pin
        rc = rc ? 1 : 0; // if rc contains a value, set to 1, else set to 0
        return rc;
    }
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-14 18:25
    Thanks jazzed, now the program works as expected. I press the button, the LED goes on, release the button, and the LED goes off. So, now the tool chest is starting to grow, we got PinInput(), PinHigh(), PinLow(), and pause(). Would their be any reason to have a PinOutput() function? Is their anything else that could be done to a pin, that would make the tool chest more valuable?

    On another note, it seems like their are only two 'C' users here, RossH, and jazzed. If they ever left, I would be up the creek, without a paddle. If there are any more 'C' users, they must be lurking, and waiting for this thread to reach the expert level. Oh well, I will just keep muddling along, and then when nobody offers up any help, or suggestions, I will probably let the thread go dead.

    Ray


    //test9.c
    
    #include <propeller.h>
    
    int PinInput(int a)
    {
        DIRA &= ~(1 << a);  // Direction state.
        return(INA & (1 << a) ? 1 : 0);  
    }
    
    void PinHigh(int a)
    {
        DIRA |= (1 << a);  // Direction state.
        OUTA |= (1 << a);  // Output state.
    }
    
    void PinLow(int a)
    {
        DIRA |= (1 << a);  // Direction state.
        OUTA &= !(1 << a); // Output state.
    }
    
    void pause(int a)
    {
        msleep(a);
    }
    
    
    main()
    {
       // Added some code just to
       // see if it compiles.
       int b;
       PinHigh(6);  // Just to test the LED.
       pause(1000);
       PinLow(6);
        while(1)
        {  
            b=PinInput(7);
            if (b == 1)
            {  
                PinHigh(6);
                pause(250);
                PinLow(6);
                pause(250);
            }
        }
    }
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-14 21:34
    This program is a little longer, and somewhat more complex. What I am trying to do is, using a remote control (Sony IR Code), with an IR demodulator (pin 7), light up LED16 on the demo board. The program compiled, but the LED16 does not go on when I press the Power Button on the remote. I tried to convert JonnyMac's code listing that was utilized for the propBASIC compiler, it seemed like a good place to start. I know that the PinInput() function works as advertised, so the problem is in the GetSircs() function, or the processCode() function. I would guess it's probably both, but can not nail down the problem. I guess I need some experts on this, once we get this to work then we will have a sircs function in Spin, pBASIC, SX/B, propBASIC, and 'C'.

    Ray


    //test10.c
    
    #include <propeller.h>
    
    #define IRpin 7
    
    int PinInput(int a)
    {
        DIRA &= ~(1 << a);
        return(INA & (1 << a) ? 1 : 0);
    }
    
    int GetSircs(long irCode)
    {
        long sWide;
        long irBits;
        
        do
        {
            sWide = PinInput(IRpin);
        }while (sWide > 2160);
        
        irCode = 0;
        
        for (irBits = 0; irBits = 11; irBits++)
        {
            irCode = irCode >> 1;
            sWide = PinInput(IRpin);
                if (sWide > 1080)
                {
                    irCode = irCode | 0x800;
                }
        }
        return(irCode);
    }
    
    void processCode()
    {
        int keyIn;
        int GetKey;
        
        keyIn = GetSircs(GetKey);
        if (keyIn == 21)  // Power button.
        {
            keyIn = (1 << keyIn);
            PinHigh(16);
            pause(2000);
            PinLow(16);
        }
    }
    
    void PinHigh(int a)
    {
        DIRA |= (1 << a);
        OUTA |= (1 << a);
    }
    
    void PinLow(int a)
    {
        DIRA |= (1 << a);
        OUTA &= !(1 << a);
    }
    
    void pause(int a)
    {
        msleep(a);
    }
    
    main()
    {
    
        //int a;
        
        while(1)
        {
            processCode();
        }
        
    }
    
    
    
  • ImageCraftImageCraft Posts: 348
    edited 2010-02-14 22:45
    Hi, thank you for your enthusiasm in trying out C and ICCPROP. The main issues with your latest example is that I think you are copying and pasting code and modifying into C but did not evaluate the logic thoroughly. For example, you have

    int PinInput(int a)
    {
    ...
    return(INA & (1 << a) ? 1 : 0);
    }

    int GetSircs(long irCode)
    {
    ...
    do
    {
    sWide = PinInput(IRpin);
    }while (sWide > 2160);

    ***
    So on one hand, PinInput returns either 1 or 0, but then you have a do-while loop that apparently expects it to return some value related to 2160. Well, it won't ever happen. It will return 0 or 1.

    Further down, you have

    int GetKey;

    keyIn = GetSircs(GetKey);

    Well, it's almost never a good sign that you are calling a function with an uninitialized variable, so what's your intention here?

    Looking at the GetSircs code, you have

    irCode = 0;

    Well, OK then, GetSircs does not really take an argument? Then it should not and you need to rewrite it that way.


    ***
    Bottom line, if you are converting from an existing example, it would be worthwhile to think about what the original program does, and think about the semantics of the language you are converting to, and find the best match.

    Good luck.

    // richard
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-15 11:15
    As richard pointed out, I did not not apply any analysis, or logic to the last example. I guess my main attempt was to put some code up, and then work my through it. I guess this points out the pitfalls of cutting, and pasting code.

    Now, what is it that I am after? On the breadboard I have a IR demodulator, its job is to take an IR signal, which is 38KHz, translate it to 0 or 1. The PinInput() function does just that, takes an instance of the pin, and captures the state, in terms of 0 and 1. The next step, how do we make sense of a 38KHz signal, in terms of 0 and 1, being presented to a pin? I guess the first problem, what does the code look like in order to achieve this. I am thinking that the 2160 number is an attempt at synchronization of 38KHz. So, the do ... while (... 2160) loop is a way of getting in sink with that signal? I think that in pbasic the pulsin command does that, so in 'C' I guess we need an equivalent function or lines of code. The problem to resolve is, create some code that can translate the 38KHz signal. If memory serves, SIRC is sent in eleven bit format, will have to look up what is what in that eleven bits. The next step will be is to capture, and translate the bits, and do a specific task. For the time being, press the power button on the remote, and have LED16 turn on, and off. Am I on the right track in terms of using the do ... while( ... 2160) to sync up with a 38KHz signal?

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-15 13:12
    I am going to try this approach, deal with the specifics of the GetSircs() function. As mentioned in the previous post, you have to get the information coming in on the IRpin. I guess I have to figure out if the :
    do
    {
    sWide = PinInput(IRpin);
    }while (sWide > 2160);
    is going to get me where I want to go. What is really going on, (sWide > 2160), is the setting for the do ... while to end, but, since the sWide variable is only getting 0 or 1, the do ... while, will never end. So, how do I get it to sync up with 38KHz, and get the correct data coming in. Maybe what I need is:
    int syncNo;
    do
    {
    // the actual code to get the bits goes in here.
    } while(syncNo > 2160);
    A big assumption here is that the 2160 number is what is needed to get it in sync with 38KHz. I remember when I was looking at the sirc code for the SX/B, it was in an interrupt, and the interrupt was set at a specific repetition. Here, I suppose, the do ... while loop should act as that repetition. I guess I need some feed back on this line of thought.

    Ray



    int GetSircs(long irCode)
    {
        long sWide;
        long irBits;
        
        do
        {
            sWide = PinInput(IRpin);
        }while (sWide > 2160);
        
        irCode = 0;
        
        for (irBits = 0; irBits = 11; irBits++)
        {
            irCode = irCode >> 1;
            sWide = PinInput(IRpin);
                if (sWide > 1080)
                {
                    irCode = irCode | 0x800;
                }
        }
        return(irCode);
    }
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-15 15:45
    I think I bit off more than I can chew on this one. But, I will still try to muddle through on this. After doing some reading, I have to figure out how to deal with the measuring of pulses. In pbasic, 'pulsin', and 'rctime' are the commands that are used. In ICC, I did not see any equivalent functions, I guess those equivalent functions have to be created, or figure out how to get the pulse of a pin. Since I have the PinInput() function, which tells me the state of the pin in a particular instance, I think that I would need to set it to some time equivalent. For the SIRC code the particular pulse rates are:
    Start pulse = 2.4 ms
    Resting states = 0.6 ms
    Binary-0 data pulse durations = 0.6 ms
    Binary-1 data pulse durations = 1.2 ms
    Do I need to use a 'for' loop, a 'do ... while' loop, or does this have to be done in assembly?

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-15 19:57
    Here is my latest attempt, the program works. When I press any button on the remote LED16 goes on/off, then LED23 goes on/off. Wanted to get some code down where I know the values are being passed, in this case, is GetSircs() getting run, and is it returning a value. The unexpected problem that I have is, the GetSircs() function, when I use 'b=PinInput(IRpin);', I have to use 'if (b == 0)' to light up the LEDs. I thought that state of the IRpin would be '0', and would only go to '1' when a button on the remote was pushed. So, that means that the IR demodulator is keeping the IRpin in a '1' state, and then when I push the button on the remote it changes the IRpin state to a '0'? If that is the case then I can see where you would have to use pulses to get something done. Now I have to figure out a way to check for pulses. This program works because by pushing a button, any button, on the remote it changes the state of the IRpin, it's long ways off from getting the button code an acting on that.


    Ray


    //test11.c
    
    #include <propeller.h>
    
    #define IRpin 7
    
    int PinInput(int a)
    {
        DIRA &= ~(1 << a);
        return(INA & (1 << a) ? 1 : 0);
    }
    
    int GetSircs(long irCode)
    {
        int b;
        do
        {
            b=PinInput(IRpin);
            if (b == 0)
            {
                PinHigh(16);
                pause(1000);
                PinLow(16);
                irCode=b;
                break;
            }
        }while(1);
        return(irCode);
    }
    
    void PinHigh(int a)
    {
        DIRA |= (1 << a);
        OUTA |= (1 << a);
    }
    
    void PinLow(int a)
    {
        DIRA |= (1 << a);
        OUTA &= !(1 << a);
    }
    
    void pause(int a)
    {
        msleep(a);
    }
    
    
    main()
    {
        long Code;
        long a;
        
        while(1)
        {
            Code = GetSircs(a);
            if (Code == 0)
            {
                PinHigh(23);
                pause(1000);
                PinLow(23);
            }
        }
    }
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-15 20:20
    Try this for measuring your pulse time down to 1/CLKFREQ precision. It is not tested, but the idea should work (assuming it is bug free).

    #include <propeller.h> // for CLKFREQ, etc... macros
    
    /*
    The purpose of this function is to search for a state *val* on pin number, and
    report the width of a pulse with the logic state if any that appears on the pin.
    The function waits for the state *val* to appear (WAITPEQ) and then wait for
    the state to not be *val* WAITPNE.
    
    Parameters and return definition:
    @param pin - this is the pin number where the pulse will be measured.
    @param val - this is the state val (0 or 1) of the pulse to measure.
    @return an integer representing the number of nanoseconds*10 that the
    pulse state *val* occurred.
    
    The function will block until the val state (1 or 0) is found.
    Best to use this code when the pin state is known.
    */
    int PulseTime(int pin, int val)
    {
      long t0 = 0;
      long t1 = 0;
      int mask = 1 << pin; // get a mask
      int state = (val & 1) << pin; // val should be set to 0 or 1
    
      DIRA &= ~mask; // set pin to input
    
      // wait until pin value == state ... waiting for valid state for measurement
      // this can hang if the pin state is always not equal to value
      WAITPEQ(mask,state);
    
      t0 = CNT; // get start count
    
      // wait while pin value == state ... measure pulse
      // this can hang if the pin state is always equal to value
      WAITPNE(mask,state);
    
      t1 = CNT; // get end count
      t1 -= t0; // get diff 30 - 15 = 15.  2 - -13 = 15 ....
    
      return (int) (t1*1000000000)/CLKFREQ; // scaled division yields t1*ns*10
    }
    
    


    Edit: Fixed comments to match intent of function.

    Post Edited (jazzed) : 2/16/2010 3:10:58 AM GMT
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-15 21:57
    @jazzed, Thanks. I am not sure if I am using your function correctly, I put it in the GetSircs() function where I am checking for non zero value, to test it out, but the LEDs do not light up, that means that it is hanging on that function. Maybe I am just using it incorrectly, I am not sure as to what the return value is supposed to be. Why does your function, when placed below the main(), compile? I thought for sure it would have to be above the main().

    Ray


    //test11.c
    
    #include <propeller.h>
    
    #define IRpin 7
    
    int PinInput(int a)
    {
        DIRA &= ~(1 << a);
        return(INA & (1 << a) ? 1 : 0);
    }
    
    int GetSircs(long irCode)
    {
        int b;
        int c;
        do
        {
            c = PulseTime(IRpin,250);
            if (c > 0)
            {
                break;
            }
            b=PinInput(IRpin);
            if (b == 0)
            {
                PinHigh(16);
                pause(1000);
                PinLow(16);
                irCode=b;
                break;
            }
        }while(1);
        return(irCode);
    }
    
    void PinHigh(int a)
    {
        DIRA |= (1 << a);
        OUTA |= (1 << a);
    }
    
    void PinLow(int a)
    {
        DIRA |= (1 << a);
        OUTA &= !(1 << a);
    }
    
    void pause(int a)
    {
        msleep(a);
    }
    
    
    main()
    {
        long Code;
        long a;
        
        while(1)
        {
            Code = GetSircs(a);
            if (Code == 0)
            {
                PinHigh(23);
                pause(1000);
                PinLow(23);
            }
        }
    }
    
    //#include <propeller.h> // for CLKFREQ, etc... macros
    
    int PulseTime(int pin, int val)
    {
    
      long t0 = 0;
      long t1 = 0;
      int mask = 1 << pin; // get a mask
      int state = (val & 1) << pin; // val should be set to 0 or 1
    
      DIRA &= ~mask; // set pin to input
    
      // wait while pin value == state ... waiting for pulse to change
      // for measurement
      WAITPEQ(mask,state); // this can hang if the pin state is always 
                           // equal to value
    
      t0 = CNT; // get start count
    
      // wait while pin value != state ... measure pulse
      WAITPNE(mask,state); // this can hang if the pin state is always not
                           // equal to value
    
      t1 = CNT; // get end count
    
      t1 -= t0; // get diff 30 - 15 = 15.  2 - -13 = 15 ....
    
      return (int) (t1*1000000000)/CLKFREQ; // scaled division yields t1*ns*10
    }
    
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-15 23:39
    Rsadeika said...
    ... Maybe I am just using it incorrectly, I am not sure as to what the return value is supposed to be.
    /*
    The purpose of this function is to search for a state *val* on pin number,
    and report the width of a pulse with the logic state if any that appears on the pin.
    The function waits for the state*val* to appear WAITPEQ and then wait for it to be
    not *val* WAITPNE.
    The comments in the first code snippet seem indicate the opposite ... sorry about that.
    
    @param pin - this is the pin number where the pulse will be measured.
    @param val - this is the state val (0 or 1) of the pulse to measure i.e. not-val val not-val
    @return an integer representing the number of nanoseconds*10 that the pulse state *val* occurred.
    */
    int PulseTime(int pin, int val);
    
    

    Rsadeika said...
    ... Why does your function, when placed below the main(), compile? I thought for sure it would have to be above the main().
    The default return type for ANSI C functions is *int* .... If the function returned something
    else or even nothing (void) an error would be generated. A good compiler will generate a
    warning for this situation.
    
  • ImageCraftImageCraft Posts: 348
    edited 2010-02-16 01:26
    Rsadeika said...
    @jazzed, Thanks. I am not sure if I am using your function correctly, I put it in the GetSircs() function where I am checking for non zero value, to test it out, but the LEDs do not light up, that means that it is hanging on that function. Maybe I am just using it incorrectly, I am not sure as to what the return value is supposed to be. Why does your function, when placed below the main(), compile? I thought for sure it would have to be above the main().

    Ray

    Ray, think of the compiler is processing your file from beginning to end, when you make a function call, it needs to know information about the function, e.g. its return and argument types. This is known as the function declaration. If you define a function, it can also serve as its declaration. The key point is, it's a beginning to end processing so your declaration must be present for the compiler to know its signature. C is actually a bit lax about it, using the "Miranda rule" - if it doesn't see a function declaration, then it gives you one. If you give it incomplete information (e.g. the function return type, but not the argument types), then it will make some assumption. If later on, if the information matches, then all is well. Otherwise, the compiler complains. Unfortunately, C is also designed to be multiple module (i.e. multiple files) with no requirement for cross-module checking.

    THIS IS ONE OF THE REASONS why they say C gives you plenty of ropes to hang yourself.

    Bottom line: read on some books or web column on "C Best Practices." For example, a common practice is to declare all externally visible functions in a header file, etc.

    // richard
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-16 11:48
    Now, that I have used ICC for awhile, I guess I can make some more observations. I was very surprised to see that there were no built in functions like 'high', and 'low'. You would think that would be a given. Since the propeller library had to be made, functions like that would have been very easy to do. The first thing that you do with a new microprocessor is build little circuits with LEDs, as a debugging tool. It would be nice to have those types of functions already made, and ready to use. These kinds of things might dampen the learning curve for somebody that is just starting to use the product.

    The ICC IDE, I found to be bug free, so far, and fairly easy to use. There is a little learning curve associated with the proper use of the IDE. I finally got to like the projects thing, if used properly, it is a time saver. So, the overall experience with the IDE, has been positive. I am sure that ImageCraft has probably gotten feedback on this, and the next IDE, will probably be a lot friendlier, and easier to use. The documentation has to be improved, that is all I will say about that.

    The big question still remains, will I be pursuing ICC further? What I am looking for is, what I describe as a 'Prototyping Language'. Something that has a lot of built in functions (commands), can be expanded somewhat, in terms of functions, and has the lowest possible learning curve. It is a real time saver if you do not have to declare functions, or worry to much about the actual placement of that function. Has to have just one type of routine, if you have to start dealing with declaration of functions, and sub-routines, that gets to be a PIA. And if it is a freebie, the promoters of the product should not get upset when some criticism is encountered. These are just some of the highlights, there is plenty more, probably worthy of its own thread.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-16 15:12
    As a change of pace, I want to look into the VGA, keyboard, and mouse programs. I noticed that the keyboard program uses TV_text.h, well I have a VGA monitor handy. Would the easiest way to accomplish this be, add the keyboard files to the vga_text project, or add the vga_text files to the keyboard project? I would also like to add the mouse files to the mix, so I could have a VGA monitor, keyboard, and mouse working as one program. I guess it would be an overload to add an SD card reader, besides the fact that there are no C drivers for that. I had the VGA program that comes with ICC up, and running. I also installed, and ran the offering by jazzed, the two look very similar, if not exact.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2010-02-16 16:27
    Rsadeika said...
    I had the VGA program that comes with ICC up, and running. I also installed, and ran the offering by jazzed, the two look very similar, if not exact.
    The two are indeed the same.
    I "invented" a way to do it using existing PASM drivers which accelerated the usefulness of ICC.

    Adoption of C on today's Propeller is a challenge for various reasons.

    * Spin/PASM are a better fit literally. Every instruction in C is 4 bytes (with LMM)
    where as many of Spin's instructions are 1 byte. C is too big for today's Propeller.

    * C must use LMM which is interpreted and executes at most 4 MIPS on a Propeller
    running at 80MHz. There are better comparable alternatives for C in the microcontroller
    world that run at 20 MIPS where memory is not a constant barrier to success.

    * Most C programmers are institutionalized and inflexible. They don't want to
    "think different" and Propeller requires that. Most C programmers would rather
    use industry standard practices like threaded programming. If anyone can do it,
    that affects their job security and self-worth [noparse]:)[/noparse]

    * Most Propeller customers used Basic Stamp first. In large part this means that
    PBASIC and it's built-in commands is what most customers would rather use.
    Learning C for most Basic Stamp users is probably not worth the effort.

    The next Propeller will provide better platform for C, but some challenges will remain.
    Load/startup method/time will become annoying for some users.
    Not having a native GNU tool-chain for Propeller will impede C user adoption.
  • RossHRossH Posts: 5,519
    edited 2010-02-16 21:06
    Jazzed,

    C'mon ... you know I'm going to diasagree with just about everything you just said ... smile.gif
    Jazzed said...
    Spin/PASM are a better fit literally. Every instruction in C is 4 bytes (with LMM) where as many of Spin's instructions are 1 byte. C is too big for today's Propeller.

    You can run programs of thousands of lines of C on the Prop I quite easily - even without external RAM. The majority of SPIN programs are only a few hundreds of lines anyway (partly because SPIN is not a good language for large projects), and could easily be re-coded in C to run up to 4 times faster (see next point).
    Jazzed said...
    C must use LMM which is interpreted and executes at most 4 MIPS on a Propeller running at 80MHz. There are better comparable alternatives for C in the microcontroller world that run at 20 MIPS where memory is not a constant barrier to success.

    SPIN is interpreted, C (even under LMM) is native. And C runs 4 times faster than SPIN.
    Jazzed said...
    Most C programmers are institutionalized and inflexible. They don't want to "think different" and Propeller requires that. Most C programmers would rather use industry standard practices like threaded programming. If anyone can do it, that affects their job security and self-worth [noparse]:)[/noparse]

    I assume you are speaking of yourself here? roll.gif
    Jazzed said...
    Most Propeller customers used Basic Stamp first. In large part this means that PBASIC and it's built-in commands is what most customers would rather use.
    Learning C for most Basic Stamp users is probably not worth the effort.

    Exisitng Propeller customers, maybe - but there are those of us who also want the Prop to succeed in the wider arena. To do that it needs more mainstream tools and languages (I mean in addition to SPIN/PASM, which I agree is a great "starter" language).
    Jazzed said...
    The next Propeller will provide better platform for C, but some challenges will remain. Load/startup method/time will become annoying for some users. Not having a native GNU tool-chain for Propeller will impede C user adoption.

    GNU is a "nice to have" but in fact C has nothing to do with GNU. ANSI C programs are portable across compilers and platforms.

    Ross.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Catalina - a FREE C compiler for the Propeller - see Catalina
  • jazzedjazzed Posts: 11,803
    edited 2010-02-16 21:15
    RossH said...
    GNU is a "nice to have" but in fact C has nothing to do with GNU. ANSI C programs are portable across compilers and platforms.
    Ok, go compile Linux with LCC based C89 ANSI C [noparse]:)[/noparse] Next you'll imply that Linux is irrelevant too [noparse]:)[/noparse]
    Friendly debate. No one is upset here.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-16 21:26
    OK, so who is right. Don't stop now, lets get this debate over and done with, so we all know what the real status of C is as pertains to the propeller. This will be good for Catalina, ICC, and everybody.

    Ray
Sign In or Register to comment.