Shop OBEX P1 Docs P2 Docs Learn Events
[Solved] Cogc acting funny, can't read PAR variable — Parallax Forums

[Solved] Cogc acting funny, can't read PAR variable

DavidZemonDavidZemon Posts: 2,973
edited 2016-01-02 18:05 in Propeller 1
Main file:
#include <PropWare/PropWare.h>
#include <PropWare/pin.h>
#include <PropWare/printer/printer.h>

int main() {
    extern const unsigned int *cogc_test_code2;
    int                       newCog = cognew(cogc_test_code2, PropWare::Pin::P16);

    pwOut << "New cog = " << newCog << '\n';

    while (1)
        PropWare::Pin::flash_pin(PropWare::Pin::P23);
}

Cogc file:
#include <propeller.h>

_NAKED int main () {
    int ledMask = 0x10000;  // Works
    //int ledMask = PAR;    // Does not work :'(
    DIRA |= ledMask;

    const unsigned int delay = CLKFREQ >> 2;
    unsigned int timer = delay + CNT;
    while (1) {
        OUTA ^= ledMask;
        timer = waitcnt2(timer, delay);
    }
}

extern unsigned int _load_start_cogc_test_cog[];
const unsigned int *cogc_test_code2 = _load_start_cogc_test_cog;

Pin 23 is always blinking correctly. The terminal always outputs "New cog = 1", which would be expected. However, if I try to read the PAR register, pin 16 does not blink. If I hardcode it, it does blink. Here's the build commands:
/opt/parallax/bin/propeller-elf-gcc    -fno-threadsafe-statics -fno-rtti -save-temps  -Os -m32bit-doubles -Wall -ffunction-sections -fdata-sections     -std=gnu++0x -mlmm -I/home/david/reusable/Documents/Programming/PropellerProjects/PropWare/CMakeModules/.. -I/home/david/reusable/Documents/Programming/PropellerProjects/PropWare/CMakeModules/../simple    -o CMakeFiles/CogcppTest_Demo.dir/CogcppTest_Demo.cpp.obj -c /home/david/reusable/Documents/Programming/PropellerProjects/PropWare/Examples/PropWare_CogcppTest/CogcppTest_Demo.cpp

/opt/parallax/bin/propeller-elf-gcc    -fno-threadsafe-statics -fno-rtti -mcog -xc++ -r -save-temps  -Os -m32bit-doubles -Wall -ffunction-sections -fdata-sections     -std=gnu++0x   -I/home/david/reusable/Documents/Programming/PropellerProjects/PropWare/CMakeModules/.. -I/home/david/reusable/Documents/Programming/PropellerProjects/PropWare/CMakeModules/../simple    -o CMakeFiles/CogcppTest_Demo.dir/cogc_test.cogcpp.cog /home/david/reusable/Documents/Programming/PropellerProjects/PropWare/Examples/PropWare_CogcppTest/cogc_test.cogcpp

/opt/parallax/bin/propeller-elf-objcopy --localize-text --rename-section .text=cogc_test.cog cogc_test.cog

/usr/pwcmake/bin/cmake -E cmake_link_script CMakeFiles/CogcppTest_Demo.dir/link.txt --verbose=1
/opt/parallax/bin/propeller-elf-gcc  -save-temps  -Os -m32bit-doubles -Wall -ffunction-sections -fdata-sections     -std=c99   -mlmm   -Wl,--gc-sections -oCogcppTest_Demo CMakeFiles/CogcppTest_Demo.dir/CogcppTest_Demo.cpp.obj CMakeFiles/CogcppTest_Demo.dir/cogc_test.cogcpp.cog  ../../PropWare/lmm/libPropWare_lmm.a ../../libpropeller/source/lmm/libLibpropeller_lmm.a ../../simple/lmm/libSimple_lmm.a 

/opt/parallax/bin/propeller-load /home/david/reusable/Documents/Programming/PropellerProjects/PropWare/bin/Examples/PropWare_CogcppTest/CogcppTest_Demo -r -t

Comments

  • Oh yea, the binary size decreases by a few bytes when I use the PAR variable and don't hardcode it, so I'm guessing something is getting optimized out that shouldn't. Almost as if PAR is not marked as volatile, and so GCC mask is assuming ledMask is always 0 and then optimizing out a few bytes of code.
  • Here's the assembly output for the cogc file when using PAR. I was wrong about the optimizer - it's fine.
    .section	.text.startup.main,"ax",@progbits
    	.balign	4
    	.global	_main
    _main
    	mov	r4, PAR
    	or	DIRA,r4
    	mov	r7, CNT
    	rdlong	r6, .LC0
    	shr	r6, #2
    	add	r7, r6
    .L2
    	xor	OUTA,r4
    	waitcnt	r7,r6
    	jmp	#.L2
    	.text
    	.balign	4
    .LC0
    	long	__clkfreq
    	.section	.text.startup.main
    	.global	_cogc_test_code2
    	.section	.data.cogc_test_code2,"aw",@progbits
    	.balign	4
    _cogc_test_code2
    	long	__load_start_cogc_test_cog
    

    And when I hardcode the pin mask:
    .section	.text.startup.main,"ax",@progbits
    	.balign	4
    	.global	_main
    _main
    	mov	r7, DIRA
    	mov	r4, .LC0
    	or	r7, r4
    	mov	DIRA, r7
    	mov	r7, CNT
    	rdlong	r6, .LC1
    	shr	r6, #2
    	add	r7, r6
    .L2
    	xor	OUTA,r4
    	waitcnt	r7,r6
    	jmp	#.L2
    	.text
    	.balign	4
    .LC0
    	long	65536
    	.balign	4
    .LC1
    	long	__clkfreq
    	.section	.text.startup.main
    	.global	_cogc_test_code2
    	.section	.data.cogc_test_code2,"aw",@progbits
    	.balign	4
    _cogc_test_code2
    	long	__load_start_cogc_test_cog
    
  • Look at the coginit documentation, PAR contains the upper 14 bits of a 16 bit address, so in your case it is always zero.
    Try to blink pins 15 to 2, it should work as they are in range, but better pass the address of a variable instead, or the pin number shifted by 2.
  • Oh... this is... shocking. And embarrassing. I've always thought a full 32-bits were passed into PAR. And as is expected now, to pass 17 I have to do trickery like:
    cognew(cogc_test_code2, 17 << 2);
    
    and
    int ledMask = 1 << (PAR >> 2);
    

    Thanks!
  • Oh wow - I had no idea that PAR wasn't a full 32 bit value either. That's a good one to know.
Sign In or Register to comment.