Please comment on my code. I'm I "getting" it ?
Bean
Posts: 8,129
Here is a small library of code I'm working on.
I think I've gotten my head around this C stuff, but I'd like you comments.
Library "stuff.c"
Main code for SimpleIDE "test.c"
Thanks,
Bean
I think I've gotten my head around this C stuff, but I'd like you comments.
Library "stuff.c"
/* high(value) - Makes pin an output and high low(value) - Makes pin an output and low input(value) - Makes pin an input output(value) - Makes pin an output pausems(value) - Pause for "value" milliseconds serinit(pin, baud) - Setup serial parameters serout(byte) - Send a byte to serial pin serstr(string) - Send a string to serial pin serint(value) - Send an integer converted to ascii to the serial pin */ #ifndef _PROPELLER_H_ #include <propeller.h> #endif #ifndef _STUFF_C_ #define _STUFF_C_ long int _serPinMask = 1 << 30; long int _serBaudCnt = 19200; void high(int given) { given = 1 << given; // Create bit mask DIRA |= given; // Make pin an output OUTA |= given; // Make pin high } void low(int given) { given = 1 << given; // Create bit mask DIRA |= given; // Make pin an output OUTA &= ~given; // Make pin low } void input(int given) { DIRA &= ~(1 << given); // Make pin an input } void output(int given) { DIRA |= 1 << given; // Make pin an output } void pausems(long int given) { if (given > 0) waitcnt(CNT + (CLKFREQ / 1000) * given); // Wait "given" milliseconds } void serinit(int g_serPin, long int g_serBaud) { _serPinMask = 1 << g_serPin; // Remember pin mask _serBaudCnt = CLKFREQ / g_serBaud; // Remember baud rate DIRA |= _serPinMask; // Make pin an output OUTA |= _serPinMask; // Make pin high } void serout(char given) { // Serial LCD character output int temp = (given << 1) + 512; // bit 0=start bit(0), bit9=stop bit(1) long int tempcnt; tempcnt = CNT + _serBaudCnt; // Setup for waitcnt int i; for (i=0; i < 10; i++) { // Sending 10 bits (start, 8-data, stop) if ((temp & 1) == 1) { // Send bit in bit0 position OUTA |= _serPinMask; } else { OUTA &= ~_serPinMask; } // if tempcnt = waitcnt2(tempcnt, _serBaudCnt); // Bit delay temp >>= 1; // Shift to get next bit in bit0 position } // for i } // serout void serstr(const char *given) { while (*given != 0) serout(*given++); // Send characters until zero } // serstr void serint(long int given) { if (given < 0) { // Check if negative value given = -given; // Use abs if negative serout('-'); // Emit a "-" if negative } int sum = 0; // Sum of digits (used to emit leading spaces) char temp = '0'; // current digit // Must do highest digit as a special case because it can only be 0-4 while (given >= 1000000000) { given -= 1000000000; temp++; sum++; } if (sum > 0) serout(temp); // If is's not zero, emit it // Do rest of digits the same way int i; for (i = 0; i < 9; i++) { char temp = '0'; while (given >= 100000000) { given -= 100000000; temp++; sum++; } if ((sum > 0) || (i == 8)) serout(temp); // If last digit(i==8) always emit given *= 10; } // for i } // serint #endif // ifndef _STUFF_C_
Main code for SimpleIDE "test.c"
#include "stuff.c" void main(void) { pausems(1000); serinit(30, 115200); // Setup for SimpleIDE terminal pausems(10); // Give pin time to settle serstr("Here we go...\n"); pausems(1000); int i; for (i=0; i < 100; i++) { serint(i); serout(10); } // for i serstr("All done...\n"); } // main
Thanks,
Bean
Comments
When I view the assembly for the test.c code it contains functions that are never called.
I though the compiler would strip those out ?
Is there any way to make it strip them out ?
Bean
I did some searching and found that if I prefix the function with "static" then they do get stripped out like I wanted.
Bean
Anyway, I'm glad to hear you're making so much progress learning GCC!
I would probably structure the project a little differently.
That is add stuff.c to the project rather than including it in test.c.
Also by doing that you don't need to add the #ifdef ... #define ... #endif block in stuff.c
The propeller.h include already has a #ifdef ... #define ... #endif block.
Here's an improvement on serout() ... What you have is very close.
The difference is placement of the tempcnt bit delay calculation.
This one works with the 115200 terminal.
I changed your test.c slightly to get this output.
With that, there are implementations of Printf, simple serial (inline serial like above) and full duplex serial (cog based), as well as DOS FAT filesystem support
I'm mentioning this because I am hoping that we can encourage more code reuse than in the past. It seems that OBEX is incredibly fragmented and has a lot of redundant code because of the fragmentation and lack of moderation or stewardship.
I love to see Bean contributing. My first Propeller project was to port the Arduino runtime to SPIN so Arduinites could have a familiar set of functions. It's funny because much of that same high level code is being rewritten here.
I *might* suggest starting with the Arduino SDK and porting their code to run on the Propeller with PGCC, it is license compatible and would save a lot of debugging effort. Obviously there are some significant architectural differences between the AVR and Propeller, but much of the SDK is agnostic and does things /the hard way/,in software
Oh, another thing to point out, with GCC, you can take advantage of a lot of optimizations that SPIN can't do. When implementing many of the pin/bit functions, you layer function calls for code compactness, but in SPIN you lose performance. In GCC you can gain that performance back by inlining functions, so the multiple stack frames get smashed, effectively reiterating the same code, but with the high level source management.