Shop OBEX P1 Docs P2 Docs Learn Events
Require specific Guide/Manual for Propeller 2 GPIO coding in c/c++ - Page 6 — Parallax Forums

Require specific Guide/Manual for Propeller 2 GPIO coding in c/c++

123468

Comments

  • evanhevanh Posts: 15,126

    Actually, my knowledge of C++ is very poor. And since FlexC supports certain class aspects of C++ it might be worth while using them. But I'm not the one to demonstrate, sorry.

  • @evanh said:
    Actually, my knowledge of C++ is very poor. And since FlexC supports certain class aspects of C++ it might be worth while using them. But I'm not the one to demonstrate, sorry.

    No problem @evanh , i will try from my side to get the PID working with P2 in c++ and will update.

  • chintan_joshichintan_joshi Posts: 135
    edited 2023-01-31 09:37

    Hello @evanh want little help for calling spin2 function from c++ file.

    I am using jm_dc.spin2 file to move DC motor.

    struct __using("jm_dc.spin2") motor_obj;
    

    now i am calling motor_obj.set_speed(15_2), this is working fine.

    But when i use any float variable value then its not working, like if i want to use

    float speed = 15.2;
    motor_obj.set_speed(speed);
    

    then this is not working, set_speed file taking it as like 100% and motor is moving with full speed, so how can i use variable instead of constant value with "_" ?

    Also if i define float speed = 15_2, then its taking it as 152 and that's also not working.

  • evanhevanh Posts: 15,126

    Floats were only recently added to Spin2. All existing code will assume 32-bit integers. I don't have that jm_dc.spin2 source code.

  • a underscore in a number is just for optical reasons, not a decimal point. Your value 15_2 is not a float 15.2 but the integer 152.

    Mike

  • JonnyMacJonnyMac Posts: 8,912
    edited 2023-01-31 16:23

    I don't use floating point in any of my Spin code. As Mike correctly states, I use an underscore to suggest where the decimal point would be when using arguments that are fractional.

    In that object I set the PWM pins for 1000 units which provides a resolution of 0.1%

      x.word[0] := 1 #> ((clkfreq/(kHz*1000)) / 100_0) <# $FFFF     ' set unit timing
      x.word[1] := 100_0                                            ' set units (0.1%)
    
  • Oh ok, my bad, i thought it was float value.

    Yes with long int its working fine. Thank you very much @evanh @msrobots @JonnyMac .

  • Hello @evanh

    Need your help for Flexprop latest version.

    My code running fine for Flexprop IDE 5.9.21.

    For Flexprop 5.9.26 if i run the code then CLK signal not changing with data.
    This is the assembly code. Which creating clock signals with data lines.

            int len = 40;
            uint32_t  m_tx = X_RFBYTE_8P_1DAC8 | pgroup<<20 | X_PINS_ON | len;  // byte wide transfers from hubRAM, via the FIFO
        uint32_t  datp = pgroup<<3 | 7<<6;
        for(int index = 0;index<rotate;index++)
        {
    
            unsigned char* haddr = &hex_t[index][0];
            int val;
    
        __asm volatile {  // no optimising and enforces Fcache use - Needed to free up the FIFO
            rdfast  #0, haddr    // setup the FIFO to read from hubRAM, non-blocking
            setxfrq m_nco1    // set sysclock/1 for lead-in timing
            xinit   leadin, #0    // lead-in timing, at sysclock/1
            setq    m_nco2    // streamer transfer rate
            xcont   m_tx, #0    // setup buffered command for tx data
    
            drvl    datp    // active data pins for tx data// declare datp as output and make value 0
            dirh    clkpin    // start smartpin internally cycling, at SPI clock rate , set clkpin as output
            NOP
            wypin   len, clkpin    // produce clocks, starting on second internal cycle
    
            // twiddle thumbs while DMA happens ...
    
            waitxfi   // wait for transfer to complete before returning back to hubexec, hubexec uses the FIFO
    
            dirl    clkpin    // reset smartpin
        _ret_   dirl    datp    // tristate the data bus upon completion
    
    leadin      long    M_LEADIN
    m_nco2      long    M_NCO
    m_nco1      long    0x8000_0000
        }
        }
    

    This is the enum we are using

    enum {
    //  _xinfreq = 20_000_000,
        _xtlfreq = 20_000_000,
        _clkfreq = 256_000_000,
        DOWNLOAD_BAUD = 230_400,
        DEBUG_BAUD = DOWNLOAD_BAUD,
    
        PINS = 20|7<<6,
        GROUP = 2,
        CLK_PIN = 6,
    
        TX_REGD = 1,
        CLK_REGD = 0,
        CPOL = 1,
        CPHA = 0,
        //CLK_DIV = 2,
        HEAPSIZE = 80000,
        CLK_DIV = 16,
        M_NCO = 0x8000_0000UL / CLK_DIV + (0x8000_0000UL % CLK_DIV > 0UL ? 1UL : 0UL),    // round up
        //M_LEADIN = X_IMM_32X1_1DAC1 | 7 + CLK_DIV + CLK_REGD - TX_REGD - (1 ^ CPHA) * (CLK_DIV>>1),
        M_LEADIN = X_IMM_32X1_1DAC1 | 5 + CLK_DIV + CLK_REGD - TX_REGD - (1 ^ CPHA) * (CLK_DIV>>1),
    
    };
    
    

    And this is how we enabled smart pin for clock and data lines

      //
        _pinf( GROUP<<3 | 7<<6 );
        _wrpin( GROUP<<3 | 7<<6, TX_REGD ? P_SYNC_IO : 0 );  // at sysclock/1, data pins should be registered to minimise relative skew
    
        _pinf( CLK_PIN );
        _pinf( LOAD );
        _wrpin( CLK_PIN, P_PULSE | P_OE | (CLK_REGD ? P_SYNC_IO : 0) | (CPOL ? P_INVERT_OUTPUT : 0) );    // clock pins
        _wxpin( CLK_PIN, CLK_DIV | (CLK_DIV>>1 + (CPOL & CLK_DIV))<<16 );    // set period and duty
    
      //     
    

    So is there any issue in assembly code execution in Flexprop latest version?
    This waveforms are from 5.9.26 version of flexprop

    And this waveforms are from 5.9.21 version of flexprop

  • evanhevanh Posts: 15,126

    @chintan_joshi said:
    My code running fine for Flexprop IDE 5.9.21.

    For Flexprop 5.9.26 if i run the code then CLK signal not changing with data.

    So is there any issue in assembly code execution in Flexprop latest version?

    Using my "pinwrite-test2.c" I just now tested a few versions of Flexspin (5.9.21, 5.9.25, 5.9.28 and 6.0.0) that I had copies of and found them all produce a correctly clocked output. So no issue with compiler.

    I'm worried about that dodgy logic analyser. It's been problematic all along!

  • evanhevanh Posts: 15,126
    edited 2023-03-15 10:47

    Ah, your LEADIN calculation is mismatched to the associated code. You've got two extra instructions that I don't have - the NOP and the drvl datp. This means the 5 should be a 9 instead.

    EDIT: Actually, the NOP can cause problems being at that spot. I recommend removing it and making the 5 a 7. Ie:

        M_LEADIN = X_IMM_32X1_1DAC1 | 7 + CLK_DIV + CLK_REGD - TX_REGD - (1 ^ CPHA) * (CLK_DIV>>1),
    

    This instruction pair should always be together (don't split them up, and don't reorder them):

            dirh   clkpin // start smartpin internally cycling, at SPI clock rate
            wypin  len, clkpin // produce clocks, starting on second internal cycle
    
  • @evanh said:
    Ah, your LEADIN calculation is mismatched to the associated code. You've got two extra instructions that I don't have - the NOP and the drvl datp. This means the 5 should be a 9 instead.

    EDIT: Actually, the NOP can cause problems being at that spot. I recommend removing it and making the 5 a 7. Ie:

      M_LEADIN = X_IMM_32X1_1DAC1 | 7 + CLK_DIV + CLK_REGD - TX_REGD - (1 ^ CPHA) * (CLK_DIV>>1),
    

    This instruction pair should always be together (don't split them up, and don't reorder them):

          dirh   clkpin // start smartpin internally cycling, at SPI clock rate
          wypin  len, clkpin // produce clocks, starting on second internal cycle
    

    Thank you for look onto this.

    That NOP i have placed intentionally to start CLOCK pulse after data pins have correct state . If i remove NOP and change M_LEADIN to 7 then data got misplaced on nozzles.
    Also if i remove drvl then code runs but no data got filled may be issue with smart pin state. This i checked just now with 5.9.21 ide version.

    But flexprop 5.9.26 ide version creating some issue in code execution , not able to get correct clock with same setup.

    If it was logic analyser issue then i should not get correct data on 5.9.21 also with same code right?

  • evanhevanh Posts: 15,126

    @chintan_joshi said:
    If it was logic analyser issue then i should not get correct data on 5.9.21 also with same code right?

    Problem is it isn't showing the actual behaviour. You know there is something going wrong but you are blind using that analyser.

  • evanhevanh Posts: 15,126

    @chintan_joshi said:
    That NOP i have placed intentionally to start CLOCK pulse after data pins have correct state . If i remove NOP and change M_LEADIN to 7 then data got misplaced on nozzles.

    That needs further investigation. There must be a good reason that a badly placed instruction happens to make it work. But need a functioning scope or analyser first!

  • @chintan_joshi said:
    But flexprop 5.9.26 ide version creating some issue in code execution , not able to get correct clock with same setup.

    If it was logic analyser issue then i should not get correct data on 5.9.21 also with same code right?

    Not necessarily. A newer version of the compiler usually produces faster code, which can expose race conditions and other timing bugs in your code.

  • @evanh and @ersmith you both may be correct about logic analyser issue, But what signals i am getting on analyser exactly same output i am getting on cartridge print.

    For example:
    if i use 5.9.21 IDE: i am getting proper print from cartridge.
    And if i changed just IDE version to 5.9.26 with same code:This prints nothing from Cartridge.

    So after that i added logic analyser to check signals, and raised issue here.

    So i am putting my point of Why changing of IDE version changing code output. Please note i can see print outputs as per signals and not totally dependent on logic analyser signals.

  • @ersmith said:

    @chintan_joshi said:
    But flexprop 5.9.26 ide version creating some issue in code execution , not able to get correct clock with same setup.

    If it was logic analyser issue then i should not get correct data on 5.9.21 also with same code right?

    Not necessarily. A newer version of the compiler usually produces faster code, which can expose race conditions and other timing bugs in your code.

    Yes @ersmith , faster code execution may create issue in signal timings. so if i decrease clock signal frequency then i should get clock signals properly, let me check this today and will revert with my output.

  • @ersmith I have tried to change CLK_DIV from 16 to 20 on IDE 5.9.26, this should decrease CLOCK frequency, but still getting same LOW clock when running assembly code as per above signals. and Nothing printed from cartridge. Something causing clock signal to stay low when running this assembly code, this code i am running from another cog.

    int len = 40;
            uint32_t  m_tx = X_RFBYTE_8P_1DAC8 | pgroup<<20 | X_PINS_ON | len;  // byte wide transfers from hubRAM, via the FIFO
        uint32_t  datp = pgroup<<3 | 7<<6;
        for(int index = 0;index<rotate;index++)
        {
    
            unsigned char* haddr = &hex_t[index][0];
            int val;
    
        __asm volatile {  // no optimising and enforces Fcache use - Needed to free up the FIFO
            rdfast  #0, haddr    // setup the FIFO to read from hubRAM, non-blocking
            setxfrq m_nco1    // set sysclock/1 for lead-in timing
            xinit   leadin, #0    // lead-in timing, at sysclock/1
            setq    m_nco2    // streamer transfer rate
            xcont   m_tx, #0    // setup buffered command for tx data
    
            drvl    datp    // active data pins for tx data// declare datp as output and make value 0
            dirh    clkpin    // start smartpin internally cycling, at SPI clock rate , set clkpin as output
            NOP
            wypin   len, clkpin    // produce clocks, starting on second internal cycle
    
            // twiddle thumbs while DMA happens ...
    
            waitxfi   // wait for transfer to complete before returning back to hubexec, hubexec uses the FIFO
    
            dirl    clkpin    // reset smartpin
        _ret_   dirl    datp    // tristate the data bus upon completion
    
    leadin      long    M_LEADIN
    m_nco2      long    M_NCO
    m_nco1      long    0x8000_0000
        }
        }
    
  • evanhevanh Posts: 15,126

    Time for you to make a demo program for us to run here.

  • @evanh said:
    Time for you to make a demo program for us to run here.

    Hello @evanh Yes , i have prepared demo code. and attached here. Please check demo_IDE.cpp.

    With this sample code also facing same CLOCK signal LOW issue for IDE 5.9.26.

  • @chintan_joshi : I compiled your demo with both flexspin 5.9.21 and flexspin 5.9.26, and the code generated is almost identical. The only differences are some label numbers (5.9.26 changed the way internal labels are numbered) and the code used for memcpy -- 5.9.26 has a new memcpy function that's quite a bit faster. This means that your Print_Data() function will finish more quickly in the newer compiler. This could mean that there's a timing problem between Print_Data() and the COGs. I notice you have a _waitus(10); inserted after Print_Data(); why is that there? If you increase it does that improve things?

  • chintan_joshichintan_joshi Posts: 135
    edited 2023-03-17 11:25

    @ersmith said:
    @chintan_joshi : I compiled your demo with both flexspin 5.9.21 and flexspin 5.9.26, and the code generated is almost identical. The only differences are some label numbers (5.9.26 changed the way internal labels are numbered) and the code used for memcpy -- 5.9.26 has a new memcpy function that's quite a bit faster. This means that your Print_Data() function will finish more quickly in the newer compiler. This could mean that there's a timing problem between Print_Data() and the COGs. I notice you have a _waitus(10); inserted after Print_Data(); why is that there? If you increase it does that improve things?

    Hello @ersmith _waitus(10) will not interfere with Print_Data(), because it will execute only after Print_Data() finished processing.

    Also have you checked signal outputs ? Like clock signal output?

  • @chintan_joshi said:

    @ersmith said:
    @chintan_joshi : I compiled your demo with both flexspin 5.9.21 and flexspin 5.9.26, and the code generated is almost identical. The only differences are some label numbers (5.9.26 changed the way internal labels are numbered) and the code used for memcpy -- 5.9.26 has a new memcpy function that's quite a bit faster. This means that your Print_Data() function will finish more quickly in the newer compiler. This could mean that there's a timing problem between Print_Data() and the COGs. I notice you have a _waitus(10); inserted after Print_Data(); why is that there? If you increase it does that improve things?

    Hello @ersmith _waitus(10) will not interfere with Print_Data(), because it will execute only after Print_Data() finished processing.

    The question is: why is _waitus(10) necessary? Why 10 microseconds in particular? If Print_Data becomes faster, perhaps a longer delay is required.

  • @ersmith said:

    @chintan_joshi said:

    @ersmith said:
    @chintan_joshi : I compiled your demo with both flexspin 5.9.21 and flexspin 5.9.26, and the code generated is almost identical. The only differences are some label numbers (5.9.26 changed the way internal labels are numbered) and the code used for memcpy -- 5.9.26 has a new memcpy function that's quite a bit faster. This means that your Print_Data() function will finish more quickly in the newer compiler. This could mean that there's a timing problem between Print_Data() and the COGs. I notice you have a _waitus(10); inserted after Print_Data(); why is that there? If you increase it does that improve things?

    Hello @ersmith _waitus(10) will not interfere with Print_Data(), because it will execute only after Print_Data() finished processing.

    The question is: why is _waitus(10) necessary? Why 10 microseconds in particular? If Print_Data becomes faster, perhaps a longer delay is required.

    No its not necessary, you can remove it. I have added it for another function call after Print_Data(). and that function call not require in demo code, so yes you can remove that _waitus(10)

  • evanhevanh Posts: 15,126
    edited 2023-03-17 13:25

    @evanh said:

    @chintan_joshi said:
    That NOP i have placed intentionally to start CLOCK pulse after data pins have correct state . If i remove NOP and change M_LEADIN to 7 then data got misplaced on nozzles.

    That needs further investigation. There must be a good reason that a badly placed instruction happens to make it work. But need a functioning scope or analyser first!

    Okay, I suspect I see the problem. Here's what you've got right now:

    Blue trace is CLK. The other three are databus [2:0].
    Note how CLK is lagging a little. That is because of the 5 for LEADIN compensation vs the NOP+DRVL.

    When I correct the LEADIN compensation we get this:

    And there we see what causes one issue. CMOS synchronous circuits typically clock in on a rising clock. Presumably the printhead works this way too. But the data is changing state exactly when the clock is rising. Bad situation. The clock should be adjusted ...

    First idea is simply change CPOL=0:

    Do you have a datasheet for the printhead? I can't remember if you've linked it before.

  • @evanh said:

    @evanh said:

    @chintan_joshi said:
    That NOP i have placed intentionally to start CLOCK pulse after data pins have correct state . If i remove NOP and change M_LEADIN to 7 then data got misplaced on nozzles.

    That needs further investigation. There must be a good reason that a badly placed instruction happens to make it work. But need a functioning scope or analyser first!

    Okay, I suspect I see the problem. Here's what you've got right now:

    Blue trace is CLK. The other three are databus [2:0].
    Note how CLK is lagging a little. That is because of the 5 for LEADIN compensation vs the NOP+DRVL.

    When I correct the LEADIN compensation we get this:

    And there we see what causes one issue. CMOS synchronous circuits typically clock in on a rising clock. Presumably the printhead works this way too. But the data is changing state exactly when the clock is rising. Bad situation. The clock should be adjusted ...

    First idea is simply change CPOL=0:

    Do you have a datasheet for the printhead? I can't remember if you've linked it before.

    @evanh Yes i have Printhead datasheet but its under NDA, so i can't share whole datasheet, sorry. But i can share CLK signal vs data signal showing on datasheet.

    Clock signal Typical frequency is 16 MHZ.

    Here you can see, with known state of DATA lines CLOCK signal going HIGH to LOW to fill the specific state of data 0 or 1.

    CLK and DATA should never change state at same time, otherwise it will detect false signal. so i added NOP to lag the CLOCK signal.

  • evanhevanh Posts: 15,126
    edited 2023-03-17 14:17

    @chintan_joshi said:
    CLK and DATA should never change state at same time, otherwise it will detect false signal. so i added NOP to lag the CLOCK signal.

    Oh, that's very unusual. Well, you can safely adjust LEADIN's constant to achieve the same effect. Better to do that than adding extra instructions.

    BTW: That timing diagram is next to useless.

  • evanhevanh Posts: 15,126
    edited 2023-03-17 22:42

    Okay, I've downloaded each archived zip of flexspin 5.9.21 and 5.9.26 and 5.9.28 and 6.0.2 then made separate setups for each and compiled demo_IDE.cpp with each one.

    Testing of each one produces the same output at both 4 MHz sysclock (250 kHz data clock) and at 256 MHz sysclock (16 MHz data clock).

    EDIT: Small correction - I'd edited the source to fix the LEADIN timing but guessed at slightly different compensation. Here's a screenshot from compiled with flexspin 5.9.26 and unedited source:

  • evanhevanh Posts: 15,126
    edited 2023-03-19 02:22

    There is one source edit I have to do. I remove the first line: #include <Propeller2.h>
    That header file doesn't exist.

    EDIT: Oh, looked for the file - Just had to match case - #include <propeller2.h> works. :) Not that it makes any difference.

  • Thanks for testing that, @evanh ! I thought, based on the generated assembly being almost identical, that compiling with the different flexprops should have the same effect, but it's nice to have it verified.

  • @evanh said:
    Okay, I've downloaded each archived zip of flexspin 5.9.21 and 5.9.26 and 5.9.28 and 6.0.2 then made separate setups for each and compiled demo_IDE.cpp with each one.

    Testing of each one produces the same output at both 4 MHz sysclock (250 kHz data clock) and at 256 MHz sysclock (16 MHz data clock).

    EDIT: Small correction - I'd edited the source to fix the LEADIN timing but guessed at slightly different compensation. Here's a screenshot from compiled with flexspin 5.9.26 and unedited source:

    @evanh Thank you for checking the issue. But what fix you have added to adjust LEADIN to get correct signal? If i can remove NOP with this fix then it can help a lot.

Sign In or Register to comment.