C3 and XMMC
I started a new project using the C3, now I want it too work just like the program that I have for the DNARTC board. For the C3 I am using the softRTC and I am using the XMMC mode. On the DNARTC board I was using the CMM mode, and I was starting COGs to do the background tasks, to run sht11 and my senselog. So, the big question is, how do I accomplish the same thing on the C3 board, using XMMC mode? I know threads are available, but I doubt that it could be set up too run like a COG, doing its own thing. Anybody have any ideas or suggestions?
Ray
Ray

Comments
This program, at this stage, is running as expected in LMM, and XMMC modes, so that is a good sign.
Ray
/** * blink.c * December 21, 2013 */ #include <stdio.h> #include <unistd.h> #include <propeller.h> #include "blink.h" struct { volatile struct blink_mailbox m; } par; void start(volatile void *parptr) { extern unsigned int _load_start_blink_cog[]; #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__) load_cog_driver_xmm(_load_start_blink_cog, 496, (uint32_t*)parptr); #else cognew(_load_start_blink_cog, parptr); #endif } #define MIN_GAP 400000 int main(int argc, char* argv[]) { sleep(1); printf("Hello, World!\n"); start(&par.m); return 0; }/* blink.h * December 21, 2013 */ struct blink_mailbox { };/* blink.cogc * December 21, 2013 */ #include <propeller.h> #include "blink.h" static _COGMEM unsigned int nextcnt; static _COGMEM unsigned int pin = 0x800000; static _COGMEM unsigned int waitdelay; _NATIVE void main(struct blink_mailbox *m) { _DIRA = pin; //waitcnt(CNT + CLKFREQ); //waitcnt2(_CNT, _clkfreq); while(1) { _OUTA ^= pin; //waitcnt2(_CNT, _clkfreq); } }Other than defining it, I don't see where you actually give waitdelay any value. Don't you need to provide an actual time to wait somehow? It's probably working just as you indicate but the delay is 0 plus execution time of the code in the loop.
The other thing that I noticed is that not everything will work in a cogc form, I tried using sleep(1), the cogc did not except that, for whatever reason, or at least the compiler did not like that. It also did not like waitcnt(CNT + CLKFREQ), this is standard stuff in the xxx.c program.
Ray
waitcnt(a) is nothing more than "wait until the system timer reaches this number". The normal way to accomplish a 1ms wait would be:
So you establish that you want to wait 80_000_000/1_000 ticks or 80_000 ticks. Lets say system timer is currently at 10_000 ticks.
Then you tell waitcnt() that you want to wait until timer is at 10_000+80_000 or 90_000 ticks.
I'm not familiar with waitcnt2() but waitcnt() is certainly able to fill the need to set a blink rate. You have the right syntax right in there with this earlier line which would produce a 1000ms blink rate:
This would give 1ms blink:
This would give a 100ms blink:
Ray
Exclusive OR. It acts to toggle the pin. If both values are 1 then the result is 0 and that result is stored back into _OUTA. If one bit is 0 and the other bit is 1 then it acts as a normal OR and the result is 1 and is stored back into _OUTA.
As for the actual blink of the LED, I was aware that '^=' is a toggle functionality, but what if you want set 'OUTA' so that it actually sets the pin state too a '1' or '0'? Like I mentioned earlier, in PASM 'OUTA[23] = 1' is what you would do, but in the cogc function this does not compile. Could not find the correct form to make this work in a cogc function.
Ray
/** * blink.c * December 21, 2013 */ #include <stdio.h> #include <unistd.h> #include <propeller.h> #include "blink.h" struct { unsigned stack[STACK_SIZE]; volatile struct blink_mailbox m; } par; void start(volatile void *parptr) { extern unsigned int _load_start_blink_cog[]; #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__) load_cog_driver_xmm(_load_start_blink_cog, 496, (uint32_t*)parptr); #else cognew(_load_start_blink_cog, parptr); #endif } volatile int blink_cog_count; #define MIN_GAP 400000 int main(int argc, char* argv[]) { sleep(1); printf("Hello, World!\n"); /* Not sure what this is doing?*/ par.m.wait_time = _clkfreq; // need this. start(&par.m); // This starts the blink.cogc. /* This seems to control the clock rate of blink.cogc. */ par.m.wait_time = _clkfreq; // need this. while(1) { sleep(1); printf("Count = %d\n",blink_cog_count); } return 0; }/* blink.h * December 21, 2013 */ struct blink_mailbox { unsigned int wait_time; }; #define STACK_SIZE 16/* blink.cogc * December 21, 2013 */ #include <propeller.h> #include "blink.h" static _COGMEM unsigned int nextcnt; static _COGMEM unsigned int pin = 0x800000; //P23 static _COGMEM unsigned int waitdelay; /* This variable used between the cogs. */ extern int blink_cog_count; _NATIVE void main(struct blink_mailbox *m) { // _DIRA = pin; nextcnt = _CNT + m->wait_time; while(1) { // waitdelay = m->wait_time; // This needed for pin toogle. // _OUTA ^= pin; // Toggle the pin (P23) /* Without this the value of 15 does not appear in the main cog. This seems to make the while() functional? */ nextcnt = waitcnt2(nextcnt, waitdelay); /* This variable is available to the main cog.*/ blink_cog_count = 15; } }Your blink_cog_count variable needs to be part of the mailbox, otherwise it shouldn't work.
struct blink_mailbox { unsigned int wait_time; int blink_cog_count; };m->blink_count_cog = 15;
The printf will have:
printf("Count = %d\n",par.m.blink_cog_count);
Set outa to pin mask:
OUTA |= pin; // as photomankc said OR the MASK
Clear outa to pin mask:
OUTA &= ~pin; // as photomankc said AND the inverse MASK ... ~ in C means invert
Ray
From the very small amount of information that is available, I get the impression that a cogc COG is a normal sized COG, meaning just because you are using XMMC mode, does not mean that the cogc grows beyond the ~396 byte size. Not sure how this uses the HUB memory though, does it just share the 32k?
I tried implementing the sht11.c into one of the cogc functions, the program did not like that at all. It seems that the sht11.c relies heavily on the simpletools library and the addition of a cogc function does not like simpletools.h. More experimentation is being done, I just do not know where this is heading.
Ray
/** * blink.c * December 21, 2013 */ #include <stdio.h> #include <unistd.h> #include <propeller.h> #include "blink.h" struct { unsigned stack[STACK_SIZE]; volatile struct blink_mailbox m; } par; void start(volatile void *parptr) { extern unsigned int _load_start_blink_cog[]; extern unsigned int _load_start_blink2_cog[]; #if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__) load_cog_driver_xmm(_load_start_blink_cog, 496, (uint32_t*)parptr); load_cog_driver_xmm(_load_start_blink2_cog, 496, (uint32_t*)parptr); #else cognew(_load_start_blink_cog, parptr); cognew(_load_start_blink2_cog, parptr); #endif } volatile int blink_cog_count; volatile int blink2_cog_count; #define MIN_GAP 400000 int main(int argc, char* argv[]) { sleep(1); printf("Hello, World!\n"); /* Not sure what this is doing?*/ par.m.wait_time = _clkfreq; // need this. start(&par.m); // This starts the blink.cogc. /* This seems to control the clock rate of blink.cogc. */ par.m.wait_time = _clkfreq; // need this. while(1) { sleep(1); printf("Count = %d\n",blink_cog_count); // printf("Count = %d\n",blink2_cog_count); } return 0; }/* blink.h * December 21, 2013 */ struct blink_mailbox { unsigned int wait_time; }; #define STACK_SIZE 16/* blink.cogc * December 21, 2013 */ #include <propeller.h> #include "blink.h" static _COGMEM unsigned int nextcnt; static _COGMEM unsigned int pin = 0x800000; //P23 static _COGMEM unsigned int waitdelay; /* This variable used between the cogs. */ extern int blink_cog_count; _NATIVE void main(struct blink_mailbox *m) { // _DIRA = pin; nextcnt = _CNT + m->wait_time; while(1) { // waitdelay = m->wait_time; // This needed for pin toogle. // _OUTA ^= pin; // Toggle the pin (P23) /* Without this the value of 15 does not appear in the main cog. This seems to make the while() functional? */ nextcnt = waitcnt2(nextcnt, waitdelay); /* This variable is available to the main cog.*/ blink_cog_count = 15; } }/* * blink2.coc * December 21, 2013 */ #include <propeller.h> #include "blink.h" static _COGMEM unsigned int nextcnt; static _COGMEM unsigned int waitdelay; static _COGMEM unsigned int pin = 0x400000; //P22 extern int blink2_cog_count; _NATIVE void high(int pin); void low(int pin); void main(struct blink_mailbox *m) { // _DIRA = pin; nextcnt = _CNT + m->wait_time; while(1) { waitdelay = m->wait_time; // This needed for pin toogle. // _OUTA ^= pin; // Toggle the pin (P23) high(22); /* Without this the value of 15 does not appear in the main cog. This seems to make the while() functional? */ nextcnt = waitcnt2(nextcnt, waitdelay); low(22); nextcnt = waitcnt2(nextcnt, waitdelay); /* This variable is available to the main cog.*/ // blink2_cog_count = 20; } } void high(int pin) // high function definition { int mask = 1 << pin; // Set up mask OUTA |= mask; // Bitwise OR w/ OUTA & DIRA DIRA |= mask; } void low(int pin) // low function definition { int mask = 1 << pin; // Set up mask OUTA &= ~mask; // Pin output state to low DIRA |= mask; // Pin direction to output }