Shop OBEX P1 Docs P2 Docs Learn Events
Clean slate with Demoboard — Parallax Forums

Clean slate with Demoboard

RsadeikaRsadeika Posts: 3,837
edited 2012-03-02 08:08 in Propeller 1
I am putting the past experience with the C3, and GG boards behind me. Maybe someday, down the road, I will find interest in those boards again.

The keyboard demo program worked just fine, on my Demoboard, when I ran it in COG mode. I also ran it in LMM mode, I noticed a delayed reaction when I was pressing the keyboard. I think I pressed about seven keys, and then the keypresses started to appear on the screen. What should be changed in order to get the keyboard program to run correctly in LMM mode?

Is there a small VGA program that I can run to test the VGA component of the Demoboard? I am still considering a test program of keyboard, and VGA output. I am thinking, maybe there should be a test program that tests all of the components of the Demoboard, written in C of course.

Ray
«13

Comments

  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-20 08:15
    Ray,

    I was playing with the VgaText demo in the demos folder yesterday on my Demoboard. a couple gotcha's

    The SimpleIDE won't read UTF-16 files, so I needed to copy/paste the VGA.SPIN text into a new IDE file and then add that to my project (see your keyboard thread, posts 15,16, & 17). For now, cut/paste is your friend when adding existing .spin files to a SIDE project.

    The demo is also written with pins for the C3 (pin #16) if you define C3 or the PropBOE (pin #8), so you need to change the PropBOE pin definition to match the Demoboard (pin #16) and then it works just fine. I'm working on connecting the keyboard to the various outputs (serial, VGA, TV) but I'm only a weekend Propeller warrior....my day job REALLY cuts into play time!! Tshi said, it may be a while until I make any progress....unless I get stuck on a few boring conference calls this week.
  • jazzedjazzed Posts: 11,803
    edited 2012-02-20 08:34
    Hi Ray,

    There are 2 problems with delay reaction now:

    1) the serial port handler in SimpleIDE needs a fix - the loader works fine.
    I'm busting but trying to find a workable solution.

    2) the stdout needs to be set to unbuffered. Put this in your main function startup:

    /* set stdout port to non-buffered */
    setvbuf(stdout, NULL, _IONBF, 0);
  • jazzedjazzed Posts: 11,803
    edited 2012-02-20 09:02
    Actually, I think it's better just to hold off on further testing until I take care of things proper.
    I'm not having any luck with PST either.

    Thanks,
    --Steve
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-20 09:07
    Going back to basics. Below is a program that I expected to flash the LEDs 16 - 23, but instead it only flashes LED 16. This is being compiled with LMM mode. I guess maybe my brain is fried after all.

    Ray

    /*
    * test1.c
    *
    * Test the LEDs on the Demoboard.
    */
    
    #include <stdio.h>
    #include <propeller.h>
    #include "misc.h"
    
    
    
    int main()
    {
    
        int x = 16;
    
        while(1)
        {
            high(x);
            waitMS(1000);
            low(x);
            waitMS(1000);
            x = x + 1;
            if (x > 16)
            {
                x = 16;
            }
        }
    
        return 0;
    }
    
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-20 09:13
    You start x at 16, blink, increment x, check if it's greater than 16 and then reset it to 16.

    How about starting x at 16 and then checking if it's > 23 before you reset it to 16?

    if (x > 23) {
    x = 16;
    }
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-20 11:06
    Keeping it simple, repeats five times, and then ends. I ran this in COG and LMM mode, seems to be behaving as expected. How much fancier can I get with this?

    The Demoboard has an earphone plug, is there a driver for this? I am thinking every time it makes a pass, it could make some kind noise?

    Ray

    /*
    * test1.c
    *
    * Test the LEDs on the Demoboard.
    *
    */
    
    #include <stdio.h>
    #include <propeller.h>
    #include "misc.h"
    
    
    
    int main()
    {
    
        int x = 16;
        int y = 0;
    
        while(1)
        {
            high(x);
            waitMS(1000);
            low(x);
            waitMS(1000);
            x = x + 1;
            if (x >= 23)
            {
                x = 16;
                y++;
                if (y > 5)
                {
                    break;
                }
            }
        }
    
        return 0;
    }
    
    
  • denominatordenominator Posts: 242
    edited 2012-02-20 11:35
    mindrobots wrote: »
    How about starting x at 16 and then checking if it's > 23 before you reset it to 16?

    if (x > 23) {
    x = 16;
    }

    If you're looking to blink the 8 LEDs, you need to check >=23 at the end of the loop:


    if (x > 23) {
    x = 16;
    }

    Otherwise you end up toggling P24, which is connected to the mouse data line.
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-20 11:45
    True, mea culpa! I'll blame it on multi-tasking.
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-20 12:01
    I made the change to (x >= 23), and I watched the LEDs, 23 never flashes. So, I will just flash 23, and see what happens.

    Ray

    <edit> I just verified that 23 does work.<edit>
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-20 14:51
    I just noticed that my previous post is not what I wanted to convey. The LED on 23 is functional, but when I run the loop with (x >= 23) the LED, which is 23, never flashes. I think that in the program, (x >= 23) is not working as expected. I am not sure if there is a bug with '>='.

    Ray
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-20 15:14
    Ray,

    I'll go back to my original code. Assuming the pins start numbering from 0 and your high/low routines affect the pin number specified,when you got through your loop with x=23, it will blink pin 23 and then x is incremented to 24. The (x>23) condition will be true and x will be reset to 16. Back you go to the top of the loop with x=16 and the blinking starts again. 16 through 23 will blink, 24 won't.

    Sorry for contributing to any confusion.
  • denominatordenominator Posts: 242
    edited 2012-02-20 15:28
    mindrobots wrote: »
    True, mea culpa! I'll blame it on multi-tasking.
    No the mea culpa is mine! I didn't read the program closely enough, and Ray is correct that now P23 doesn't blink. Sorry! Plain > (not >=) is appropriate.

    However, this gets into why one avoids this style of code. It's so much clearer to use something like this:
    int main()
    {
        for (y = 1;  y <= 5;  y++)
        {
            for (x = 16;  x <= 23;  x++)
            {
                high(x);
                waitMS(1000);
                low(x);
                waitMS(1000);
            }
        }
        return 0;
    }
    

    Shorter, simpler, and less difficult to spot off-by-one errors.
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-20 16:02
    Here you go, Ray!

    This should work just fine on your Demoboard. It gets all 8 cogs running, all 8 LEDs (16-23) lit up and all 16 timers timing. It's a port of one of the Quickstart demo programs ported to propgcc. It shows one of the ways to start code in COGs in propgcc. It needs to be better commented but I thoguht you might like to play more.
    /**  * @file twinkle.c
      * This program is loosely ported from the Quickstart 5: Multicogtwinkledemo.spin
      * from the Parallax Semiconductor site.
      *
      * This program is targeted toward the QUICKSTART pin numebrs
      * and COG counts (up to 8)but can be adjusted as required.
      * 
      * It starts multiple COGs running the twinkle function in each COG
      * demonstrating multi-cog support for LMM c routines
      * 
      * Progress of COG initialization will be logged on stdout
      * 
      * The counters in each COG are set up to control the LED brightness
      *
      * Original SPIN program Copyright (c) 2011 Parallax, Inc.
      * This port Copyright (c) 2012 Rick Post
      * MIT Licensed (see at end of file for exact terms)
      */
      #include <stdio.h>
     #include <propeller.h>
     #include <sys/thread.h>
      #define STACK_SIZE 16
     #define COGS_TO_START 8 /* you do NOT need stack space for COG0
                             /* but we'll set aside space just to make the indexing easier
      /* stack for cogs */
     /* - pass (COG# * STACK_SIZE) + STACK_SIZE to _start_cog_thread */
     static int cog_stack[STACK_SIZE * COGS_TO_START];
      /* per-thread library variables ("Thread Local Storage") */
     static _thread_state_t thread_data[COGS_TO_START];
      /* variables that we share between cogs */
     volatile unsigned int rate[COGS_TO_START];
     volatile unsigned int pin[COGS_TO_START];
      /*
      * here's the toggle code that runs in another cog
      */
       void do_twinkle(void *arg __attribute__((unused)) )
     {
         unsigned int wait_time, counter, cognum, mask;
         cognum = cogid();
         mask = 1 << pin[cognum] ;
         DIRA = mask;
         OUTA = 0;
         CTRA = 0 + (0b0100 << 26) + pin[cognum];
         CTRB = 0 + (0b0110 << 26) + pin[cognum];
         INA = 0;
         FRQA = 0;
         PHSA = 0;
         FRQB = 0;
         PHSB = 0;
         
         while (1)
         {
         for (counter = 0; counter < 101; counter++)
             {
             FRQB = counter * (0x7fffffff / 50);
             waitcnt(rate[cognum] + CNT);
             }
         for (counter = 0; counter < 101; counter++)
             {
             FRQB = (100 - counter)* (0x7fffffff / 50);
             waitcnt(rate[cognum] + CNT);
             }
         }
     }
      /*
      * main code
      * This is the code running in the LMM cog (cog 0).
      * It launches another cog to actually run the 
      * toggling code
      */
      void main (int argc,  char* argv[])
     {
         int i, n;
          printf("Twinkle Time!\n");
         pin[0] = 16;
         rate[0] = CLKFREQ / 25;
         rate[1] = CLKFREQ / 150;
         rate[2] = CLKFREQ / 225;
         rate[3] = CLKFREQ / 50;
         rate[4] = CLKFREQ / 200;
         rate[5] = CLKFREQ / 100;
         rate[6] = CLKFREQ / 10;
         rate[7] = CLKFREQ / 75;
         /* start the new cog */
         for (i=1;i<COGS_TO_START;i++)
         {
             pin[i] = 16 + i;
             n = _start_cog_thread(cog_stack[i * COGS_TO_START]+ STACK_SIZE, do_twinkle, NULL, &thread_data[i]);
             printf("toggle cog %d has started\n", n);
         }
         
         do_twinkle(1);
      }
      /* +--------------------------------------------------------------------
      * ¦  TERMS OF USE: MIT License
      * +--------------------------------------------------------------------
      * Permission is hereby granted, free of charge, to any person obtaining
      * a copy of this software and associated documentation files
      * (the "Software"), to deal in the Software without restriction,
      * including without limitation the rights to use, copy, modify, merge,
      * publish, distribute, sublicense, and/or sell copies of the Software,
      * and to permit persons to whom the Software is furnished to do so,
      * subject to the following conditions:
      *
      * The above copyright notice and this permission notice shall be
      * included in all copies or substantial portions of the Software.
      *
      * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      * +--------------------------------------------------------------------
      */
    
    

    You should just be able to build a SIDE project around this code.
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-21 03:49
    This is an example of using the For ... Next loop, as suggested by denominator. It seems, for this job, it is the better way. Now we have two methods of testing the LEDs on the Demoboard. I will not get into the details of the 'For ... Next' statement, but I will mention, that in this case, 'x <= 23' works as expected.

    Ray

    * test2.c
    *
    * Test the LEDs on the Demoboard version 2.
    * Cleaner code logic, and more appropriate for this job?
    *
    */
    
    #include <stdio.h>
    #include <propeller.h>
    #include "misc.h"
    
    int main()
    {
        int x, y;
    
        for (y = 1;  y <= 5;  y++)
        {
            for (x = 16;  x <= 23;  x++)
            {
                high(x);
                waitMS(1000);
                low(x);
                waitMS(1000);
            }
        }
        return 0;
    }
    
    
  • LeonLeon Posts: 7,620
    edited 2012-02-21 04:15
    When to use one or the other is explained in K&R.
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-21 05:06
    Ray,

    Here's a link to a C and C++ online Tutorial

    There was another thread around here with lots of online information about learning C...of course, I can't find it now.

    The K&R Leon refers to is the classic The C Programming Language, by Kernighan and Ritchie - well worth the money. Get the 2nd edition as it is the latest and greatest! See if you can pick up a used copy someplace, it is a bit expensive but worth it!
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-21 05:27
    This is yet another, slightly fancier version. This might be it for this, but maybe not.

    I have the K&R book, that is what I used to figure out what the 'For...Next' really does.

    I had mentioned a driver for the speaker/headphones, on the Demoboard, anybody find one yet? I think adding a little noise to the finale() function might be interesting. After I get a good understanding of the stuff I just programmed, VGA will be next. Flashing LEDs, noise, and some graphics on the VGA monitor, would make a good Demoboard test example.

    Ray


    /*
    * test4.c
    *
    * Test the LEDs on the Demoboard version 3.
    * Made it little bit fancier.
    *
    * I am not putting in any comments. While it is still
    * simple concepts, you can try to figure it out.
    *
    */
    
    #include <stdio.h>
    #include <propeller.h>
    #include "misc.h"
    
    
    void finale()
    {
        int y, x = 0;
       
        while(x < 10)
        {
            for (y = 16; y <= 23; y++)
            {
                high(y);
                waitMS(10);
                low(y);
                waitMS(10);
            }
            for (y = 23; y >= 16; y--)
            {
                high(y);
                waitMS(10);
                low(y);
                waitMS(10);
            }
    
            x++;
        }
    }
    
    int main()
    {
        int x, y;
    
        for (y = 1;  y <= 2;  y++)
        {
            for (x = 16;  x <= 23;  x++)
            {
                high(x);
                waitMS(250);
                low(x);
                waitMS(250);
            }
        }
        finale();
    
        return 0;
    }
    
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-21 05:47
    Ray,

    I haven't seen any sound demos/code that's been ported from SPIN/PASM to C. There are a number of candidate objects in the OBEX that have a PASM driver that could have a wrapper written for it. That might be something to try if you use jazzed's keyboard wrappers or the VGA wrappers in the propgcc demo folder.

    At page 147 of the Propeller Education Kit (PEK) document (comes with the Propeller Tool), they start talking about making noise with a piezospeaker and the counters. This can certainly and easily be done from C. My twinkle program above uses the timers to vary the brightness of the LEDs. Same idea to vary the frequency to the speaker (or headphone jack in the Demoboards case). The PEK document is a great way to get started with the Propeller and exercise its features. At some point, there should be a C version of the PEK - maybe when the PropBOE comes out??
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-21 06:16
    For us beginners, if somebody could explain what a wrapper is, what it does, and maybe show an elementary example. I do not think we would need treatise on the subject, but a good working example would help. I do not want to turn this thread into a 'learning C', but explanations for some new concepts would be in order.

    I am considering purchasing a uSD reader from Parallax, hopefully this been through a lot of production runs, and the product is stable. The only concern that I have is, how beneficial would this be, considering the Demoboard has no no access to XMM or XMMC? Using the Dave Hine example uSD program, in LMM mode you do not have a lot of memory left over to do any thing substantial.

    Ray
  • mindrobotsmindrobots Posts: 6,506
    edited 2012-02-21 06:28
    By wrapper, I mean the .c and .h files that you use to interface to a .spin PASM file. In the case of Steve's keyboard driver example, he wrote the keyboard.h and keyboard.c code to allow a C program to call the keyboard.spin routines. There are many great SPIN objects around that have at their core PASM routines that fit into a single COG and should be useful when given a C interface. The propgcc demo folder has examples of the VGA object and the TV SPIN objects being "wrapped".

    I'm sure there will be a document/tutorial on writing this. I'm trying to figure this process out currently...there's lots of debate as to the correct way to do it, the standards a .spin should expose and use so it's easily wrappable. I just want to do a couple easy objects to make sure I understand it.

    It's like the thread/multi-cog document, lots of different ways to accomplish the same thing depending on where you are and where you need to get to.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-02-21 06:51
    Rsadeika wrote: »
    The only concern that I have is, how beneficial would this be, considering the Demoboard has no no access to XMM or XMMC? Using the Dave Hine example uSD program, in LMM mode you do not have a lot of memory left over to do any thing substantial.
    Ray, there may be more room available in LMM mode than you think. The c3files demo does command-line parsing and implements simple versions of ls, cat, echo, rm, rmdir, mkdir and stdio redirection. If you remove all this you should have quite a bit of space for your program. Also, ls, rmdir and mkdir pull in extra code from the library, so if you don't do those functions that code won't be linked in from the library.

    EDIT: You can run XMMC code directly from an SD card. I know it works on the C3 card. I don't know if it's been implemented for other cards that support SD. You would need to create a loader board description to add SD XMMC support to a board that doesn't come with an SD card connector.

    EDIT2: I stubbed out the file code in the c3files demo, and the SD support does use a significant amout of space. It looks like it uses about 15K. A minimal program with the SD file driver is around 22K in size, so that only leaves about 8K for user code. It might make sense to create a minimal file driver that doesn't support subdirectories and maybe only handles FAT16. We could try stubbing out code in FileDriver.c and dosfs.c to see how much memory we could save.
  • denominatordenominator Posts: 242
    edited 2012-02-21 11:51
    Dave Hein wrote: »
    We could try stubbing out code in FileDriver.c and dosfs.c to see how much memory we could save.

    I have this exact problem in a data logging project designing using PropGCC - the SD card code and GCC were (and in some cases still are) just taking too much space. I'm just getting ready to get the fsrw spin object to work in a separate Spin Cog, callable from C via a mailbox. The fsrw spin code takes half the space of the PropGCC SD card support code. It's interesting to note that the fsrw.c code, when compiled with PropGCC, takes just about the same amount of memory as PropGCC's SD card code.
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-22 03:25
    Is their a new problem with the 'SSER'? I tried this with an attached RS232, and I get nothing in PST window. I changed the pins to 31,30, and nothing appears in PST. Also, is there some documentation for 'SSER', I keep forgetting which are the Rx, and Tx parameters? Keep in mind I am working with the Demoboard now.

    Ray

    /*
    * fds1.c
    */
    
    #include <stdio.h>
    #include <propeller.h>
    #include "misc.h"
    
    int main()
    {
        char *serdevice = "SSER:9600,1,0";
        FILE *port = fopen(serdevice, "+r");
    
        waitMS(5000);
        fprintf(port,"This is some text.\n");
    
        while(1)
        {
            int byte = fgetc(stdin);
            fprintf(port,"%c",byte);
        }
        fclose(port);
        return 0;
    }
    
  • denominatordenominator Posts: 242
    edited 2012-02-22 05:52
    Ray,

    To change the baud rate, this code will work on the demo board:
    #include <stdio.h>
    
    int main()
    {
        freopen("SSER:9600", "w", stdout);
        while (1)
            printf("Hello World\n");
    }
    

    To change the pin numbers, use:
        freopen("SSER:9600,31,30", "w", stdout);
    

    To load to propeller for my tests I used: propeller-load -b demoboard -r -t9600 main.elf
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-22 06:46
    The changes I made below now shows the text, but I still do not get anything from a keypress. It seems odd that you would have to add another line of code to make this show some text.

    Ray

    /*
    * fds1.c
    */
    
    #include <stdio.h>
    #include <propeller.h>
    #include "misc.h"
    
    int main()
    {
        /*                           Rx Tx */
        char *serdevice = "SSER:9600,27,26";
        FILE *port = fopen(serdevice, "+r");
    
        waitMS(1000);
        freopen(serdevice, "w",port);
    
        waitMS(5000);
        fprintf(port,"This is some text.\n");
    
        while(1)
        {
            int byte = fgetc(stdin);
           /* int byte = fgetc(port); */
            fprintf(port,"%c",byte);
        }
        fclose(port);
        return 0;
    }
    
  • denominatordenominator Posts: 242
    edited 2012-02-22 07:36
    Ray,

    You don't need the fopen, just the freopen.

    Also, if you want to use stdin with a non-standard baud, you have to reopen it too. This works for me:
    #include <stdio.h>
    
    int main()
    {
        freopen("SSER:9600,31,30", "w", stdout);
        freopen("SSER:9600,31,30", "r", stdin);
    
        printf("This is some text.\n");
    
        while(1)
        {
            int byte = fgetc(stdin);
            printf("Your byte: %c\n", byte);
        }
        return 0;
    }
    

    - Ted
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-22 07:50
    I thought I would try something different, use an attached keyboard to display text, and a keypress, to an external terminal. This seems to work as expected. But I still do not understand why you have to use freopen() to make this program work.

    Ray
    /*
    * keybterm.c
    */
    
    #include <stdio.h>
    #include <propeller.h>
    #include "Keyboard.h"
    #include "misc.h"
    
    int main()
    {
        char *serdevice = "SSER:9600,1,0";
        FILE *port = fopen(serdevice, "+r");
    
        waitMS(1000);
        freopen(serdevice, "w", port);
    
        keybd_start(26,27);
        waitMS(3000);
        fprintf(port,"Keyboard Demo\n");
    
        while(1)
        {
           /* putchar(keybd_getkey()); */
            fprintf(port, "%c",keybd_getkey());
            waitMS(10);
            fflush(port);
        }
        return 0;
    }
    
  • jazzedjazzed Posts: 11,803
    edited 2012-02-22 08:57
    Hi Ray,

    The only time you really need to use freopen AFAIK is when you change a parameter on stdin or stdout (pin 30,31).

    Also, it seems the pin sequence has changed from an earlier version. It used to be "SSER:baud,tx,rx" now it's "SSER:baud,rx,tx".
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-02-22 10:29
    I think I just solved my problem with SSER thing. This is what I had in the program:
    FILE *port = fopen(serdevice, "+r");
    This line compiled without any errors or warnings. As soon as I changed the "+r" to "r+" then everything started to work as expected. I would of thought that the compiler would of picked up on that. This would of been a horrible thing to try to find if it was in a two or three hundred line program, and the program compiled without any complaints.

    Ray
  • denominatordenominator Posts: 242
    edited 2012-02-22 11:07
    jazzed wrote: »
    The only time you really need to use freopen AFAIK is when you change a parameter on stdin or stdout (pin 30,31).

    Said parameters being either the pin numbers or baud rate. In Ray's case, he's trying to change the baud rate. Isn't freopen more appropriate than fopen in this case?
Sign In or Register to comment.