For the SD example program, I noticed that there are no commands for creating a file, was that intentional?
Ray, take a look at the README.txt file in the demos/c3files directory. It shows a how files can be created by redirecting the standard output. Some examples are:
echo This is a test >file1
cat file1 >file2
cat file1 file2 >file3
ls -l >> file3
I have two GG boards, on one board, the USB connection is getting flaky, that is why I double checked in the device manager to make sure that there was a good com port. All I did was unplug from my C3 board, I had nothing else going on, hit the up arrow key to get the command line, and hit enter. On the second try, after a reboot, I typed in the load command, and the same thing happened. Basically I tried it three times, and got the same result.
Just to refresh, I am working with Windows XP Professional SP3, all updates installed.
For the ledonoff program I am not using an external com port, just the CLI window, and I do use the -t switch to put it in terminal mode. On my GG board I have an RS232 break out board, I was going to try using the ledonoff program through the external com port to see if the same thing was occurring. But, ...
I found an editor called geany, which I started to use, I kind of like it. It has a plugins, and a 'set build' option, which I can not get it to work. It comes setup for using GCC, but not propGCC. If somebody is using geany, maybe you can give me a hint as to how I can automate the compile, and execute from within the program.
I have two GG boards, on one board, the USB connection is getting flaky, that is why I double checked in the device manager to make sure that there was a good com port. All I did was unplug from my C3 board, I had nothing else going on, hit the up arrow key to get the command line, and hit enter. On the second try, after a reboot, I typed in the load command, and the same thing happened. Basically I tried it three times, and got the same result.
Just to refresh, I am working with Windows XP Professional SP3, all updates installed.
For the ledonoff program I am not using an external com port, just the CLI window, and I do use the -t switch to put it in terminal mode. On my GG board I have an RS232 break out board, I was going to try using the ledonoff program through the external com port to see if the same thing was occurring. But, ...
Ray
Ok, so you unplugged the C3 before quitting the terminal program.
Did you do that on all tries?
Can you quit the program before unplugging the C3 to see what happens?
What version of PropGCC are you using?
There was a time when the terminal would go into an infinite loop until Ctrl-C, but that has been fixed for a while.
I've tested this on Windows XP SP3 and Windows 7.
The unplug test gives me this:
c:\propgcc>propeller-load -r -t hello
Propeller Version 1 on COM8
Writing 6588 bytes to Propeller RAM.
Verifying ... Upload OK!
[ Entering terminal mode. Type ESC or Control-C to exit. ]
Hello World.
Hello World.
Hello World.
Hello World.
Hello World.
Hello World.
Hello World.
Error reading port
Access is denied.
c:\propgcc>propeller-load -r -t hello
Propeller Version 1 on COM8
Writing 6588 bytes to Propeller RAM.
Verifying ... Upload OK!
[ Entering terminal mode. Type ESC or Control-C to exit. ]
Hello World.
I found an editor called geany, which I started to use, I kind of like it. It has a plugins, and a 'set build' option, which I can not get it to work. It comes setup for using GCC, but not propGCC. If somebody is using geany, maybe you can give me a hint as to how I can automate the compile, and execute from within the program.
Ray
Nice find! I've been looking for something like this.
Geany is a perfect single file IDE. It may be able to build demos too - haven't figured it out yet.
One issue is the propeller gcc path must be set in your environment.
To do this, in Windows XP (similar for Windows 7):
Click start
Then right-click My Computer
Then right-click Properties
Then click Advanced Tab
Then click Environment Variables button
Then at the top control, click the Add button
Enter PATH in the new dialog top text box
Enter C:\propgcc\bin in the new dialog bottom text box
Click ok until all windows disappear.
Start Geany
In Geany Menu Build -> Set Build Commands, add these:
OK, lets try the GG board steps again. I plug the USB cable into the GG board, I power up the GG board. I go to the device manager to check if I have a good com port. I start propgcc.bat, and type in:
-propeller-load -p com5 ledonoff -r -t
then I get the error code, and the CLI window is basically hung up
Then I have to reboot because the task manager will not kill the task.
When I had a linux box available I used geany to work with some small programs like "Hello, World". I liked it because it was set up for GCC, all I had to do is type in the program, hit compile, and then execute, everything worked.
OK, lets try the GG board steps again. I plug the USB cable into the GG board, I power up the GG board. I go to the device manager to check if I have a good com port. I start propgcc.bat, and type in:
-propeller-load -p com5 ledonoff -r -t
then I get the error code, and the CLI window is basically hung up
Ray, what error code are you getting?
Do you have a propgcc_v0_2_0 or greater version package?
Can you copy/paste the command line window text here?
What happens if you use this only? propeller-load ledonoff -r
GG USB board.
I used geany this time to build and execute, the result is the same:
error writing port
a device attached to the system is not functioning
I just ran the Propeller Tool v1.3. 'Identify Hardware', and it now shows an error window "Access violation at address 00404974 in module 'Propeller.exe'. Read of address 00000060." So, now I do not know what is going on. Time to do something else ...
GG USB board.
I used geany this time to build and execute, the result is the same:
error writing port
a device attached to the system is not functioning
I just ran the Propeller Tool v1.3. 'Identify Hardware', and it now shows an error window "Access violation at address 00404974 in module 'Propeller.exe'. Read of address 00000060." So, now I do not know what is going on. Time to do something else ...
Ray
This sounds a lot like the USB is broken some way. Does your C3 behave the same?
Have you tried a different cable or a different USB port on your computer?
I found another USB cable, now the one GG USB board seems to be behaving. The other GG USB board seems to have a bad or flaky USB connector, I expected lot better product quality from GG, I will leave it at that.
The C3 board has been working as expected, so far. With the addition of Geany, programming, using propGCC, has become bearable. It's unfortunate that Geany does not do multiple file compilation, so the SD example has to be done the hard way. The other thing about Geany is it may become a pain when you want to compile using -mxmm, or -mxmmc, so it seems that Geany is good, but not that good.
Since I have access to an external RS232 port, I am now working with the Full_Duplex_Serial example. When I compile the code below I get a compilation error:
-undefined reference to
'_fdx_start'
'_fdx_puts'
'_fdx_rx'
'_fdx_tx'
The 'full_duplex_serial_ht.h' file contains the definitions which have I located in the same folder as FDSerial.c. I get the impression that the compiler is not finding the header file or it is not reading the file or both. Is the compiler experiencing folder depth complexity problems, or is it something else?
Ray
// FDSerial.c
#include <stdio.h>
#include <propeller.h>
#include "full_duplex_serial_ht.h"
char textdisplay[] = "This is the FDSerial program\n";
char temp;
int i;
int main (int argc, char* argv[])
{
_DIRA = 0;
_OUTA = 0;
fdx_start(26, 27, 115200);
fdx_puts(textdisplay);
while(1)
{
#ifdef ECHO_BIN
temp = fdx_rx();
for (i = 0; i < 8; i++)
{
if (temp & 0x80)
{
fdx_tx('1');
}
else
{
fdx_tx('0');
}
temp <<= 1;
}
fdx_tx('\n');
#else
fdx_tx(fdx_rx());
#endif
}
}
The demo full_duplex_serial_ht is a great demo, but it is not our standard Full Duplex serial library.
If you want to use that demo, I'll dig it further for you or maybe heater can help out since he wrote it.
We have 2 standard IO serial library drivers: FullDuplexSerial and SimpleSerial.
SimpleSerial is normally used unless FullDuplexSerial is setup in the driver list.
FullDuplexSerial uses another COG and must be added with the _Driver* array.
OK, I looked at the two references that you supplied, but I did not get very much out of it. It did not give me any insight as to the correct way of initializing FullDuplexSerial. I also did not find the functions for sending a byte, sending a string, receiving a byte, receiving a string, ..., etc. I think that I have been spoiled by the openWatcom references, and examples to support the library functions.
You will probably be getting people that have been working with Spin, and are used to looking at things like FullDuplexSerial.spin, which shows all the methods and how to use them. It seems to me that if people are expected to dig into developing programs on their own, the least we could use is some, no, a lot of existing, documented information. Again I mention the openWatcom initiative. Since it has been mentioned that PropGCC is going to BETA, how are "regular" programmers expected to test the software? We can not keep running multiple variations of a "Hello, World!" program. What better way to test an ALPHA software program than to use real programming examples.
I am not trying to be harsh, but if you want a successful software package you will need a lot more useable documentation that programmers can actually use. Now, I may have missed all that information, maybe there is a document already existing, just point me in the right direction.
You have valid concerns about the examples. I think the examples make sense for someone that is experienced in C, but they are confusing for someone who is more experienced in Spin. And to be honest, there are some things that are easy to do in Spin, but become a bit complicated when using standard I/O in C. Functions like fdx.rx and fdx.rxcheck require doing some "special" things to duplicate this with standard I/O. However, C is fully capable of doing low-level drivers like the Spin FullDuplexSerial that don't use standard I/O. The full_duplex_serial_ht demo implements some of that, but it does not implement all of the FDS methods.
It would be good to have some demos that duplicates the functionality in Spin. At the very least we should include Spin-like demos that interface to seriall, TV, mouse, keyboards, VGA, and maybe an I2C EEPROM demo.
I was looking through all of the folders in propGCC, and I did not find the propeller.h file, I think that as a new user you would want to see a document that listed all the useable headers for the propeller.
It has been mentioned that propGCC is going to offered as an alternative for working with the propBOE, so is the main selling point going to be "You have to be an expert in C", before you can use the software. I do not think that will get you very much traction. You would think that there would be an emphasis on the information needed to be able to use it with propeller related things, like propBOE, propeller DEMO board, C3, ..., etc. And I also think that giving the example of "You can blink an LED" will get old very quickly. As for the professionals, the first thing that they will be looking for is the documentation for the propeller.h file, after all this is supposed to be used with a Propeller, right?
Early in the Alpha program, there were a few tutorial documents written to address the various combinations of new prop user/old prop user new C user/old C user. During the Alpha tests, the compiler was to dynamic to actually write tutorials for. As it enters Beta testing, I (for one) plan on starting up the tutorial writing again. These first documents are out on the Google code wiki, I believe.
As an alternative to, NOT replacement for Spin, I would expect it to have similar levels of documentation as well as documents and examples to help an experienced Prop user without C experience transition to PropGCC.
I have been working with Parallax to arrange for documentation that is consistent with Parallax's high quality and ease of use. Please understand that the PropGCC Wiki documents are feed-stock for that documentation. As you have noticed we still have work to do.
I was looking through all of the folders in propGCC, and I did not find the propeller.h file, I think that as a new user you would want to see a document that listed all the useable headers for the propeller.
Point taken. Today propeller.h is the only specialized header and can be found in: propgcc/propeller-elf/include with the other header files. More libraries are in development and will be rolled-out on a reasonable schedule.
It has been mentioned that propGCC is going to offered as an alternative for working with the propBOE, so is the main selling point going to be "You have to be an expert in C", before you can use the software.
Please understand that PropBOE is a Parallax Education product that will live up to the high standards of the Education group when released for sale in the Education market.
As I understand it, Spin/PASM will be released first, and C will follow.
C (and C++ to a point) has become an absolute requirement in much of the Education market - this is a huge factor, so it is being treated seriously. Your input and many others will help make the product stronger; this is why we are conducting a public alpha.
We appreciate all participation, and your's is especially cherished.
As for the professionals, the first thing that they will be looking for is the documentation for the propeller.h file, after all this is supposed to be used with a Propeller, right?
Most Professional GCC users will find propeller.h quickly and it is documented in the file. However, assuming the case is fully covered is like walking in a mine field.
OK, I looked at the two references that you supplied, but I did not get very much out of it. It did not give me any insight as to the correct way of initializing FullDuplexSerial.
By default according to the example I gave above, the driver will be initialized to IO P30/P31 (TX/RX) and 115200.
A way to change these parameters has been designed, but I'm having trouble with it. I'll get back with an update later.
Update:
The FullDuplexSerial "FDS:" driver has problems with freopen in the v0_2_2 release.
The SimpleSerial "SSER:" driver works fine though. Here is an example:
/*
* Compile and load with:
* propeller-elf-gcc -Os -Wall -o hello hello.c
* propeller-load -r -t38400 hello
*/
#include <stdio.h>
#include <propeller.h>
int main(void)
{
// this is an example similar to that described in the library.html document
// unfortunately at time of this update, the document is wrong.
freopen("SSER:38400,31,30", "w", stdout);
for(;;) {
printf("Hello World.\n");
waitcnt(CLKFREQ+CNT);
}
return 0;
}
I tried the small example, and it works, although it just displays to the CLI as terminal screen. I think that I have been doing this all along by using -t. So, what was supposed to change?
On my GG USB board I have an RS232 breakout connect to pins 27,26 on the GG board, I would like to send out a string of text. I am assuming that the freopen() order is still BAUD,Txpin,Rxpin? Now I did try the 27,26 values, and I was not getting anything on my external terminal program which is connected to COM1.
I think you guys are going to get bored of my questions, but that is OK, I am persistent, and eventually I will get what I need.
I tried the small example, and it works, although it just displays to the CLI as terminal screen. I think that I have been doing this all along by using -t. So, what was supposed to change?
I think you guys are going to get bored of my questions, but that is OK, I am persistent, and eventually I will get what I need.
Not bored at all. Keep them coming.
I think the syntax is a little wrong in the Library.html file. It seems to be BAUD,RX,TX ...
To add a new serial port, you should be able to use this example:
void printSomeText(void)
{
FILE* port = fopen("SSER:57600,26,27","r+"); // assuming 26 is RX and 27 is TX
fprintf(port, "some text\n"); // fprintf is just like printf except you can use another port
fclose(port); // close port when finished
}
This is my interpretation of a simple serial, and I mean simple, C program. I compiled and loaded, it ran as expected, no surprises in the compile and load sequence. A brief recap, GG USB board with an RS232 breakout attached to pins 27, and 26. I am using a C# simple serial program via the COM1 port, which I am developing as I work with the Prop-GCC stuff.
Are there some functions for doing Rx (byte and string size), and a way of doing Tx (byte, and decimal size). Their are more things that I could think of, but I will ask for it in small portions.
Ray
// fds2.c
//
// A very simple serial program, not sure if you can even call it that.
//
// Compile and Load:
// propeller-elf-gcc -Os -Wall -o fds2 fds2.c
// propeller-load -r fds2
//
#include <stdio.h>
#include <propeller.h>
void printsometext(void)
{
/* BAUD Rx Tx ? */
FILE* port = fopen("SSER:38400,27,26","r+");
fprintf(port, "This is some text.\n");
fclose(port);
}
int main(void)
{
for (;;) /* Another way of doing a forever loop. */
{
printsometext();
waitcnt(CLKFREQ+CNT); /* This is a pause, needs to be impoved.*/
}
return 0;
}
Below is fds3.c, it runs on my setup, GG USB board. Hopefully somebody tries this out to see if it works on their setup. Next thing I will do is hook up the RS232 breakout to my C3 board, and try to run it with -mxmm.
Hopefully there will be some more input as to the Rx stuff, so I can expand the external terminal program for input to the C3. A small project could be the ability to do an LED on/off by typing in some commands via the external terminal program.
This is a good opportunity for the "C experts" to make their comments about the program(s), that way everybody will learn. I think I have developed a thick skin, so I should be able to withstand the criticism.
Ray
// fds3.c
//
// Combination simple serial program, and LED on/off.
// Compile and Load:
// propeller-elf-gcc -Os -Wall -o fds3 fds3.c
#include <stdio.h>
#include <propeller.h>
/* Set port info BAUD Rx Tx */
char openstat[] = "SSER:115200,27,26";
/* 1000 = 1 second */
int waitMS(int WCtime)
{
waitcnt(((80000000/1000)*WCtime) + CNT);
return WCtime;
}
/* 1 = second */
int wait(int WCtime)
{
waitcnt((80000000 * WCtime) + CNT);
return WCtime;
}
/* pin number */
int high(int WCpin)
{
DIRA = 1 << WCpin;
OUTA = 1 << WCpin;
return WCpin;
}
/* pin number */
int low(int WCpin)
{
DIRA = 1 << WCpin;
OUTA = 0 << WCpin;
return WCpin;
}
int main(void)
{
/* Open the COM port */
FILE* port = fopen(openstat, "r+");
while(1)
{
/* Prints to external port terminal program */
fprintf(port, "This is some text\n");
waitMS(2000); /* Wait 2 seconds */
/* Turn on/off LED connected to pin 25 */
high(25);
wait(3); /* Wait 3 seconds */
low(25);
}
fclose(port);
return 0;
}
Are there some functions for doing Rx (byte and string size), and a way of doing Tx (byte, and decimal size). Their are more things that I could think of, but I will ask for it in small portions.
C has powerful standard functions for doing what you want to do with serial I/O.
Some examples:
/* standard input from serial port */
int console_byte = getchar();
[LEFT]
/* reading byte from a port */
FILE *port = fopen("SSER:115200,27,26","r+");
int serport_byte = getc(port);
/* reading from standard input */
char buff[128];
int hexbyte;
scanf("%x",&hexbyte);
fflush(stdin); /* often used with scanf to make sure the input buffer is clean */
char buff[128];
int hexbyte;
fscanf(port,"%x",&hexbyte);
fflush(port);
printf("Value of %c is %d or %02x hex\n", 'A', 'A', 'A'); /* should give Value of A is 65 or 41 hex */
fprintf(port,"Value of %c is %d or %02x hex\n", 'A', 'A', 'A'); /* should give Value of A is 65 or 41 hex */
[/LEFT]
As you can see, the C way to do "console" input and output (serial terminal in this case) is varied.
If you are doing only console I/O on P30/31, you can use a compiler trick to reduce code
size but it is not fully standard compliant, so not all printf() syntax would work.
This is a good opportunity for the "C experts" to make their comments about the program(s), that way everybody will learn. I think I have developed a thick skin, so I should be able to withstand the criticism.
May I suggest "review", "evaluation", or the artsy related "critique" rather than criticism?
Regarding a peer review:
First, please understand that what I've learned as a professional that being too "it should be this way or none!" just plain causes grief unless there is a defined coding standard to follow. The standard that I use is to generally follow the originator's coding standard.
Second, my comments will be to enhance readability and spot errors. Remember however that readable is subjective. Consistency is a mark of readability.
Finally, your code is not so bad.
So, here's my peer review.
1. For multiple line comments I recommend using /* */ instead of // ... see below.
// fds3.c
//
// Combination simple serial program, and LED on/off.
// Compile and Load:
// propeller-elf-gcc -Os -Wall -o fds3 fds3.c
/*
* file fds3.c
*
* Combination simple serial program, and LED on/off.
* Compile and Load:
* propeller-elf-gcc -Os -Wall -o fds3 fds3.c
*/
2. I would make the waitMS comment multi-line and use different a different waitcnt statement. Same for the wait function.
/* 1000 = 1 second */
int waitMS(int WCtime)
{
waitcnt(((80000000/1000)*WCtime) + CNT);
return WCtime;
}
/*
* wait WCtime milliseconds with RCFAST or better clock config like xtal1 + PLL16x.
* 1000 = 1 second
*
* param WCtime - number of milliseconds to wait
*/
int waitMS(int WCtime)
{
/* wait using the propeller.h CLKFREQ which might be any value */
waitcnt(((CLKFREQ/1000)*WCtime) + CNT);
return WCtime;
}
3. I would re-write these. The main problem is that DIRA = value destroys other pins.
/* pin number */
int high(int WCpin)
{
DIRA = 1 << WCpin;
OUTA = 1 << WCpin;
return WCpin;
}
/* pin number */
int low(int WCpin)
{
DIRA = 1 << WCpin;
OUTA = 0 << WCpin;
return WCpin;
}
/*
* set a pin high without affecting others
* param WCpin = pin number to set high
*/
void high(int WCpin)
{
unsigned int bits = 1 << WCpin;
DIRA |= bits;
OUTA |= bits;
}
/*
* set a pin low without affecting others
* param WCpin = pin number to set low
*/
void low(int WCpin)
{
unsigned int mask = 1 << WCpin;
DIRA |= mask;
OUTA &= ~mask;
}
I recommending using these commands for your xmm experiments ($ is a prompt in linux).
This generally provides the best possible xmm performance on C3 because only code is fetched from external memory. Both local variables (stack) and data are kept in HUB RAM in XMMC mode.
So, the -mxmmc flag says build and XMMC program that puts all code in Flash and all data in HUB. This is different from XMM mode in that all data and code will be stored in C3 SPI-RAM and Flash.
The -b c3f flag says use all of the c3 cache for flash. You could also use -b c3, but only half of the cache would be used for flash.
3. I would re-write these. The main problem is that DIRA = value destroys other pins.
/* pin number */
int high(int WCpin)
{
DIRA = 1 << WCpin;
OUTA = 1 << WCpin;
return WCpin;
}
/* pin number */
int low(int WCpin)
{
DIRA = 1 << WCpin;
OUTA = 0 << WCpin;
return WCpin;
}
/*
* set a pin high without affecting others
* param WCpin = pin number to set high
*/
void high(int WCpin)
{
unsigned int bits = 1 << WCpin;
DIRA |= bits;
OUTA |= bits;
}
/*
* set a pin low without affecting others
* param WCpin = pin number to set low
*/
void low(int WCpin)
{
unsigned int mask = 1 << WCpin;
DIRA &= ~mask;
OUTA &= ~mask;
}
Jazzed's low() routine isn't an exact analog of the original low. It sets the pin to high-Z (floating). An exact analog would be:
/*
* set a pin low without affecting others
* param WCpin = pin number to set low
*/
void low(int WCpin)
{
unsigned int mask = 1 << WCpin;
DIRA |= mask;
OUTA &= ~mask;
}
However, when using Catalina, I kind of got used to its _dira() and _outa() that both mask and set. Here's what I now use to set and reset pins with GCC:
//
// This macro is useful for converting a PIO number to a bit mask
//
#define PIO(x) (1 << x)
//
// These macros make bit-banging a little clearer
//
#define mask_dira(mask, value) (DIRA = ((DIRA & ~(mask)) | ((value) & (mask))))
#define mask_outa(mask, value) (OUTA = ((OUTA & ~(mask)) | ((value) & (mask))))
//
// These constants make our intended bit operations a bit more clear.
//
#define ALL_BITS -1
#define NO_BITS 0
This would yield:
/*
* set a pin high without affecting others
* param WCpin = pin number to set high
*/
void high(int WCpin)
{
mask_dira(PIO(WCpin), ALLBITS);
mask_outa(PIO(WCpin), ALLBITS);
}
/*
* set a pin low without affecting others
* param WCpin = pin number to set low
*/
void low(int WCpin)
{
mask_dira(PIO(WCpin), NOBITS);
mask_outa(PIO(WCpin), ALLBITS);
}
A couple of notes:
(1) Don't worry about the seeming "big hammer" approach vis-a-vis your eventual code size. PropGCC's optimization is amazing and it will optimize this stuff down to a very minimal set of assembly operations that you need to get the masking/setting done.
(2) These examples don't necessarily show the descriptive power of what these mask_* macros can do. Consider these example instead:
mask_dira(PIO(18) | PIO(17) | PIO(16), ALLBITS); // Set P18-16 to output mode
mask_outa(PIO(17) | PIO(1), NOBITS); // Set P17 and P1 to zero
mask_outa(PIO(18) | PIO(17) | PIO(16), 0b011 << 16); // Set P18-16 to "011" (P18=0, P17=1, P16=1)
The nice things here are:
(A) The ability to atomically set more than one PIO bit at a time.
(B) A more-or-less descriptive declaration of what you're trying to do. I've been programming for almost 40 years, and I still make a occasional mistake when bit-banging with &, |, ~, etc. When using these macros, there's no doubt that you are getting the mask correct, and they almost read like spin's equivalent:
I just realized I made the same mistake of messing up the bit-banging in low()! The correct code is:
/*
* set a pin low without affecting others
* param WCpin = pin number to set low
*/
void low(int WCpin)
{
mask_dira(PIO(WCpin), ALLBITS);
mask_outa(PIO(WCpin), NOBITS);
}
Jazzed's low() routine isn't an exact analog of the original low. It sets the pin to high-Z (floating). An exact analog would be:
/*
* set a pin low without affecting others
* param WCpin = pin number to set low
*/
void low(int WCpin)
{
unsigned int mask = 1 << WCpin;
DIRA |= mask;
OUTA &= ~mask;
}
Below I am using misc.h header file, just to see how that works, works as expected. It seems like there is less clutter in main program. Anything to look out for when using local header files?
My programming style right now is, I use Geany to create the file, and develop the program, then I use build to do the preliminary compile to see what the errors are. The thing that I need to do now is create some batch file(s) so I can use the fancy commands the jazzed listed to do the compiles. Does anybody remember what the batch file commands would be for doing something like:
xHOc.bat fds4 fds4.c
This could be expanded to do multiple file compiles also, I guess.
It is common knowledge that Parallax is developing the Eclipse Prop-GCC IDE, but who will be maintaining, and doing further development of Prop-GCC? I am hoping that Prop-GCC does not go dormant like Spin development.
Ray
/* fds4.c
*
* Combination simple serial program, and LED on/off.
* Added the use of header file that now contains misc functions.
* Compile and Load:
* propeller-elf -Os -Wall -o fds4 fds4.c
*
* Feb 03, 2012
*/
#include <stdio.h>
#include <propeller.h>
#include "misc.h"
char openstat[] = "SSER:115200,23,22";
int main(void)
{
FILE* port = fopen(openstat, "r+");
while(1)
{
fprintf(port, "This is the LED on/off program.\n");
high(21);
fprintf(port, "LED on\n");
waitMS(1500);
low(21);
fprintf(port, "LED off\n");
wait(2);
}
fclose(port);
return 0;
}
/* misc.h */
/* #include <propeller.h> */
/*
* 1000 = 1 second
* param WCtime - number of milliseconds to wait.
*/
int waitMS(int WCtime)
{
waitcnt(((CLKFREQ/1000)*WCtime) + CNT);
return WCtime;
}
/*
* param 1 = second
* param WCtime - number of seconds to wait.
*/
int wait(int WCtime)
{
waitcnt((CLKFREQ * WCtime) + CNT);
return WCtime;
}
/*
* Set a pin high without affecting other pins.
* param WCpin = pin number to set high.
*/
int high(int WCpin)
{
unsigned int bits = 1 << WCpin;
DIRA |= bits;
OUTA |= bits;
return WCpin;
}
/*
* Set a pin low without affecting other pins.
* param WCpin = pin number to set low.
*/
int low(int WCpin)
{
unsigned int mask = 1 << WCpin;
DIRA |= mask;
OUTA &= ~mask;
return WCpin;
}
This works if you are in the folder where you have the files. Still not sure how I would accomplish multiple file compiles using the command line batch file?
Comments
echo This is a test >file1
cat file1 >file2
cat file1 file2 >file3
ls -l >> file3
Just to refresh, I am working with Windows XP Professional SP3, all updates installed.
For the ledonoff program I am not using an external com port, just the CLI window, and I do use the -t switch to put it in terminal mode. On my GG board I have an RS232 break out board, I was going to try using the ledonoff program through the external com port to see if the same thing was occurring. But, ...
Ray
Ray
Ok, so you unplugged the C3 before quitting the terminal program.
Did you do that on all tries?
Can you quit the program before unplugging the C3 to see what happens?
What version of PropGCC are you using?
There was a time when the terminal would go into an infinite loop until Ctrl-C, but that has been fixed for a while.
I've tested this on Windows XP SP3 and Windows 7.
The unplug test gives me this:
Nice find! I've been looking for something like this.
Geany is a perfect single file IDE. It may be able to build demos too - haven't figured it out yet.
One issue is the propeller gcc path must be set in your environment.
To do this, in Windows XP (similar for Windows 7):
- Click start
- Then right-click My Computer
- Then right-click Properties
- Then click Advanced Tab
- Then click Environment Variables button
- Then at the top control, click the Add button
- Enter PATH in the new dialog top text box
- Enter C:\propgcc\bin in the new dialog bottom text box
- Click ok until all windows disappear.
- Start Geany
In Geany Menu Build -> Set Build Commands, add these:C commands
- Compile button: propeller-elf-gcc -Wall -c -Os "%f"
- Build button: propeller-elf-gcc -Wall -Os -o "%e" "%f" -s
Execute commands- propeller-load -r -t "./%e"
After that you can add your single source file, then click on build, and then execute.Using multiple files will be more complicated and will require make. I have a program that might be able to fix that though.
-propeller-load -p com5 ledonoff -r -t
then I get the error code, and the CLI window is basically hung up
Then I have to reboot because the task manager will not kill the task.
When I had a linux box available I used geany to work with some small programs like "Hello, World". I liked it because it was set up for GCC, all I had to do is type in the program, hit compile, and then execute, everything worked.
Ray
Ray, what error code are you getting?
Do you have a propgcc_v0_2_0 or greater version package?
Can you copy/paste the command line window text here?
What happens if you use this only? propeller-load ledonoff -r
GG USB board.
I used geany this time to build and execute, the result is the same:
error writing port
a device attached to the system is not functioning
I just ran the Propeller Tool v1.3. 'Identify Hardware', and it now shows an error window "Access violation at address 00404974 in module 'Propeller.exe'. Read of address 00000060." So, now I do not know what is going on. Time to do something else ...
Ray
Have you tried a different cable or a different USB port on your computer?
The C3 board has been working as expected, so far. With the addition of Geany, programming, using propGCC, has become bearable. It's unfortunate that Geany does not do multiple file compilation, so the SD example has to be done the hard way. The other thing about Geany is it may become a pain when you want to compile using -mxmm, or -mxmmc, so it seems that Geany is good, but not that good.
Ray
-undefined reference to
'_fdx_start'
'_fdx_puts'
'_fdx_rx'
'_fdx_tx'
The 'full_duplex_serial_ht.h' file contains the definitions which have I located in the same folder as FDSerial.c. I get the impression that the compiler is not finding the header file or it is not reading the file or both. Is the compiler experiencing folder depth complexity problems, or is it something else?
Ray
Sorry you had to ditch that GG USB board.
The demo full_duplex_serial_ht is a great demo, but it is not our standard Full Duplex serial library.
If you want to use that demo, I'll dig it further for you or maybe heater can help out since he wrote it.
We have 2 standard IO serial library drivers: FullDuplexSerial and SimpleSerial.
SimpleSerial is normally used unless FullDuplexSerial is setup in the driver list.
FullDuplexSerial uses another COG and must be added with the _Driver* array.
See Propeller GCC library and standard IO drivers for more details.
You can include the full duplex driver by adding it to your program like below.
There are demos that show how to use TvText and VgaText also.
You will probably be getting people that have been working with Spin, and are used to looking at things like FullDuplexSerial.spin, which shows all the methods and how to use them. It seems to me that if people are expected to dig into developing programs on their own, the least we could use is some, no, a lot of existing, documented information. Again I mention the openWatcom initiative. Since it has been mentioned that PropGCC is going to BETA, how are "regular" programmers expected to test the software? We can not keep running multiple variations of a "Hello, World!" program. What better way to test an ALPHA software program than to use real programming examples.
I am not trying to be harsh, but if you want a successful software package you will need a lot more useable documentation that programmers can actually use. Now, I may have missed all that information, maybe there is a document already existing, just point me in the right direction.
Ray
You have valid concerns about the examples. I think the examples make sense for someone that is experienced in C, but they are confusing for someone who is more experienced in Spin. And to be honest, there are some things that are easy to do in Spin, but become a bit complicated when using standard I/O in C. Functions like fdx.rx and fdx.rxcheck require doing some "special" things to duplicate this with standard I/O. However, C is fully capable of doing low-level drivers like the Spin FullDuplexSerial that don't use standard I/O. The full_duplex_serial_ht demo implements some of that, but it does not implement all of the FDS methods.
It would be good to have some demos that duplicates the functionality in Spin. At the very least we should include Spin-like demos that interface to seriall, TV, mouse, keyboards, VGA, and maybe an I2C EEPROM demo.
Dave
It has been mentioned that propGCC is going to offered as an alternative for working with the propBOE, so is the main selling point going to be "You have to be an expert in C", before you can use the software. I do not think that will get you very much traction. You would think that there would be an emphasis on the information needed to be able to use it with propeller related things, like propBOE, propeller DEMO board, C3, ..., etc. And I also think that giving the example of "You can blink an LED" will get old very quickly. As for the professionals, the first thing that they will be looking for is the documentation for the propeller.h file, after all this is supposed to be used with a Propeller, right?
Ray
Early in the Alpha program, there were a few tutorial documents written to address the various combinations of new prop user/old prop user new C user/old C user. During the Alpha tests, the compiler was to dynamic to actually write tutorials for. As it enters Beta testing, I (for one) plan on starting up the tutorial writing again. These first documents are out on the Google code wiki, I believe.
As an alternative to, NOT replacement for Spin, I would expect it to have similar levels of documentation as well as documents and examples to help an experienced Prop user without C experience transition to PropGCC.
That's my thoughts and plans anyway.
I have been working with Parallax to arrange for documentation that is consistent with Parallax's high quality and ease of use. Please understand that the PropGCC Wiki documents are feed-stock for that documentation. As you have noticed we still have work to do.
Point taken. Today propeller.h is the only specialized header and can be found in: propgcc/propeller-elf/include with the other header files. More libraries are in development and will be rolled-out on a reasonable schedule.
Please understand that PropBOE is a Parallax Education product that will live up to the high standards of the Education group when released for sale in the Education market.
As I understand it, Spin/PASM will be released first, and C will follow.
C (and C++ to a point) has become an absolute requirement in much of the Education market - this is a huge factor, so it is being treated seriously. Your input and many others will help make the product stronger; this is why we are conducting a public alpha.
We appreciate all participation, and your's is especially cherished.
Indeed!
Try this attached demo (courtesy of Dave Hein) with your C3. Use load command: propeller-load -r -b c3f vgademo.elf
vgademo.zip
Most Professional GCC users will find propeller.h quickly and it is documented in the file. However, assuming the case is fully covered is like walking in a mine field.
By default according to the example I gave above, the driver will be initialized to IO P30/P31 (TX/RX) and 115200.
A way to change these parameters has been designed, but I'm having trouble with it. I'll get back with an update later.
Update:
The FullDuplexSerial "FDS:" driver has problems with freopen in the v0_2_2 release.
The SimpleSerial "SSER:" driver works fine though. Here is an example:
On my GG USB board I have an RS232 breakout connect to pins 27,26 on the GG board, I would like to send out a string of text. I am assuming that the freopen() order is still BAUD,Txpin,Rxpin? Now I did try the 27,26 values, and I was not getting anything on my external terminal program which is connected to COM1.
I think you guys are going to get bored of my questions, but that is OK, I am persistent, and eventually I will get what I need.
Ray
Not bored at all. Keep them coming.
I think the syntax is a little wrong in the Library.html file. It seems to be BAUD,RX,TX ...
To add a new serial port, you should be able to use this example:
Let me know if that helps.
Are there some functions for doing Rx (byte and string size), and a way of doing Tx (byte, and decimal size). Their are more things that I could think of, but I will ask for it in small portions.
Ray
Hopefully there will be some more input as to the Rx stuff, so I can expand the external terminal program for input to the C3. A small project could be the ability to do an LED on/off by typing in some commands via the external terminal program.
This is a good opportunity for the "C experts" to make their comments about the program(s), that way everybody will learn. I think I have developed a thick skin, so I should be able to withstand the criticism.
Ray
Good to see you're having luck with things. I'll comment on your newer post in a bit.
C has powerful standard functions for doing what you want to do with serial I/O.
Some examples:
As you can see, the C way to do "console" input and output (serial terminal in this case) is varied.
Console input is achieve using getc(), getchar(), fgetc(), gets(), fgets(), and scanf().
I recommend reading these pages for *get* usage:
http://linux.die.net/man/3/getc and http://www.manpagez.com/man/3/getc/
The scanf function is made for formatted input: http://www.manpagez.com/man/3/scanf/
Console output is done with putchar(), fputc(), printf(), and fprintf().
See this page for printf and friends:
http://linux.die.net/man/3/printf and http://www.manpagez.com/man/3/printf/
If you are doing only console I/O on P30/31, you can use a compiler trick to reduce code
size but it is not fully standard compliant, so not all printf() syntax would work.
What does that example do?
- -Os means optimize for size.
- -o means hello is the output program filename
- -Dprintf=__simple_printf means use the simple and smaller printf
- hello.c means compile the hello.c file
- -s mean remove debug information so you'll know how big the propeller image really is
Hope this helps.--Steve
Regarding a peer review:
First, please understand that what I've learned as a professional that being too "it should be this way or none!" just plain causes grief unless there is a defined coding standard to follow. The standard that I use is to generally follow the originator's coding standard.
Second, my comments will be to enhance readability and spot errors. Remember however that readable is subjective. Consistency is a mark of readability.
Finally, your code is not so bad.
So, here's my peer review.
1. For multiple line comments I recommend using /* */ instead of // ... see below.
2. I would make the waitMS comment multi-line and use different a different waitcnt statement. Same for the wait function.
3. I would re-write these. The main problem is that DIRA = value destroys other pins.
I recommending using these commands for your xmm experiments ($ is a prompt in linux).
$ propeller-elf-gcc -mxmmc -Os -o fds3 -Dprintf=__simple_printf fds3.c -s
$ propeller-load -r -t fds3 -b c3f
This generally provides the best possible xmm performance on C3 because only code is fetched from external memory. Both local variables (stack) and data are kept in HUB RAM in XMMC mode.
So, the -mxmmc flag says build and XMMC program that puts all code in Flash and all data in HUB. This is different from XMM mode in that all data and code will be stored in C3 SPI-RAM and Flash.
The -b c3f flag says use all of the c3 cache for flash. You could also use -b c3, but only half of the cache would be used for flash.
Jazzed's low() routine isn't an exact analog of the original low. It sets the pin to high-Z (floating). An exact analog would be:
However, when using Catalina, I kind of got used to its _dira() and _outa() that both mask and set. Here's what I now use to set and reset pins with GCC:
This would yield:
A couple of notes:
(1) Don't worry about the seeming "big hammer" approach vis-a-vis your eventual code size. PropGCC's optimization is amazing and it will optimize this stuff down to a very minimal set of assembly operations that you need to get the masking/setting done.
(2) These examples don't necessarily show the descriptive power of what these mask_* macros can do. Consider these example instead:
The nice things here are:
(A) The ability to atomically set more than one PIO bit at a time.
(B) A more-or-less descriptive declaration of what you're trying to do. I've been programming for almost 40 years, and I still make a occasional mistake when bit-banging with &, |, ~, etc. When using these macros, there's no doubt that you are getting the mask correct, and they almost read like spin's equivalent:
DIRA[18..16]~~
OUTA[17]~ OUTA[11]~
OUTA[18..16] = %010
Enjoy!
I'll correct my post with attribution.
--Steve
My programming style right now is, I use Geany to create the file, and develop the program, then I use build to do the preliminary compile to see what the errors are. The thing that I need to do now is create some batch file(s) so I can use the fancy commands the jazzed listed to do the compiles. Does anybody remember what the batch file commands would be for doing something like:
xHOc.bat fds4 fds4.c
This could be expanded to do multiple file compiles also, I guess.
It is common knowledge that Parallax is developing the Eclipse Prop-GCC IDE, but who will be maintaining, and doing further development of Prop-GCC? I am hoping that Prop-GCC does not go dormant like Spin development.
Ray
To compile using xmm:
Command line: xHOc ./fds4 ./fds4.c
To load:
Command line: xHOl ./fds4
This works if you are in the folder where you have the files. Still not sure how I would accomplish multiple file compiles using the command line batch file?
Ray