Shop OBEX P1 Docs P2 Docs Learn Events
flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler - Page 80 — Parallax Forums

flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

17778808283122

Comments

  • RaymanRayman Posts: 14,648

    @ersmith I tried something that didn't work... Maybe there's no way it could?

    @Ahle2 music code requires that you call PollTick() every so often.
    I tried to jump to this function from the vga assembly driver.

    Did this to have a way to get pointer to function:
    typedef void (*SoundOperation)(NULL);
    And then this to tell vga driver the location of the function:

        SoundOperation pPollTick = sound.pollTick;  //RJA having video driver update music during refresh
        vga.ConfigurePollTick(pPollTick);
    

    And in the vga assembly driver, I had this:

                call    PollTickAddress 'update music
                jmp     #field                  'loop
    

    I'm sure this was wishful thinking, but is there any way to make something like that work?

  • @Rayman: sorry, I'm still not quite sure of the setup. Is PollTick a Spin function? And you want to call it from assembly? That's a little bit complicated, because it needs both the function address and the pointer to the object that contains PollTick. Also, of course, the Spin code expects a certain environment in the COG (some built-in functions and so on) which is not likely to be compatible with the code in a driver cog.

  • RaymanRayman Posts: 14,648

    @ersmith Thanks, that's what I figured...

  • I can I do packed structures in c?

    #pragma pack(1)
    struct x {
        uint8_t sequence;
        int16_t Yaw;
        int16_t Pitch;
        int16_t Roll;
        int16_t Xacc;
        int16_t Yacc;
        int16_t Zacc;
        int8_t res[3];
        uint8_t chksum;
    } Packet;
    

    Mike

  • No, FlexC doesn't support packed structures yet.

  • RaymanRayman Posts: 14,648
    edited 2021-02-20 18:09

    When taking input from terminal window with getch(), I'm seeing some interesting responses from things like keyboard arrow keys.
    Just read that what you get isn't really standardized. But, is there a list somewhere of what to expect?
    Looks like the arrows return two numbers, first 7 and then "D" for left, "A" for up, "C" for right, and "B" for down...

    Actually, it's 27, not 7 for the first return value. Seems it also deletes the first character...
    Seems a hair flaky though... Occasionally, I'm just getting the letter, without the preceding 27...

  • @Rayman ,

    Looks like we're going to need a termcap file and program.

    Mike

  • FlexProp is at the mercy of the terminal program, but most terminal programs (including I believe the default Windows one) implement ANSI escape codes for the arrow keys:

    https://en.wikipedia.org/wiki/ANSI_escape_code#Terminal_input_sequences

    Depending on how you're reading the sequences you'll also have to be careful about timing, because the default smart pin based input has no buffer (so it's easy to lose characters). Best bet is probably to read a whole chunk of characters at once with something like read(0, buf, sizeof(buf)).

  • RaymanRayman Posts: 14,648

    Ok, makes sense now.
    Guess this means one can’t reliably use the arrows and function keys, etc.

  • evanhevanh Posts: 15,916

    /me ponders what results a smartpin with 18N1 receive framing config would produce ...

  • evanhevanh Posts: 15,916

    Oh, it's more than two characters for some keys ...

  • evanhevanh Posts: 15,916

    Man, getting the buffering logic right is always a brain twister when you're not expecting it.

    Okay, I think I'm seeing it real now. I'm getting up to 6 characters for a single key press (with shift held)! A plain arrow key is 3 characters:
    - Left: 1b 5b 44
    - Right: 1b 5b 43
    - Up: 1b 5b 41
    - Down: 1b 5b 42

  • evanhevanh Posts: 15,916

    Cool, yep, I've proven an async receive smartpin can capture up to 3 adjoined characters as a single word. It does need a little massaging to extract the characters from the included framing. And amusingly, because the longest strings for a single keypress is 6 characters then it'll also handle them too, since the smartpin can buffer the second 3 character word while the first is being decoded.

    I wouldn't call it a tidy solution ... but if you don't want to use interrupts or another cog, this will work.

  • evanhevanh Posts: 15,916

    Huh, that's unexpected, I had accidentally also configured the transmit smartpin to the same 28N1 and it worked, albeit somewhat slower. Not ideal ... fixed now.

  • evanhevanh Posts: 15,916

    Here's the new receiving code. The new part is the handling of the longword sized buffer, temp2. Which needs to be treated statically, allowing repeated calling inspections.

    There is also a config change of the rx smartpin. The frame length parameter for WXPIN uses #27 instead of #7.

    '===============================================
    '  input:  (none)
    ' result:  pb
    'scratch:  temp2
    '
    getch1
            testb   temp2, #8   wc  'framing stop-bit of prior character:  high= STOP
            testbn  temp2, #9   andc    'framing start-bit of next character:  low = START
            shr temp2, #10      'shift down next character, if any
    .loop1
        if_nc   testp   #DIAGRXPIN  wz  'word received in smartpin? (IN high == yes)
    if_nc_and_nz    jmp #.loop1         'if nothing recieved then wait
        if_nc   rdpin   temp2, #DIAGRXPIN   'get data word from smartpin Z buffer
        if_nc   shr temp2, #32-28       'shift the data to bottom of register
    
            getbyte pb, temp2, #0       'fetch character from word
            ret         wcz 'C/Z preserved
    
  • evanhevanh Posts: 15,916
    edited 2021-02-21 06:03

    Sigh, the forum software is still removing tabs. Err, no, it's changed, now it stops at representing with four spaces, instead of eight. That's certainly better than deleting them. Copying the text from the edit box preserves the tabs.

    PS: Here's the old code it's based on for comparison:

    '===============================================
    '  input:  (none)
    ' result:  pb
    'scratch:  (none)
    '
    getch
            testp   #DIAGRXPIN  wz  'byte received? (IN high == yes)
        if_z    rdpin   pb, #DIAGRXPIN      'get data from Z buffer
        if_z    shr pb, #32-8       'shift the data to bottom of register
        if_z    ret         wcz 'restore C/Z flags of calling routine
            jmp #getch          'wait while Smartpin buffer is empty
    

    PPS: The posted routine is not what I used for proving things. That code was way messier and had handling for larger strings, and timeouts to analyse and troubleshoot with.

  • Thanks @evanh . That looks quite intriguing. I take it temp2 isn't actually scratch, it needs to preserved across calls, and that it should be initialized to $FFFF_FFFF (or will 0 work)? I'm also a little concerned about what happens if two bytes are sent with an unusual number of bit periods between them -- it looks like the smart pin buffering will work well if bytes are sent back-to-back or at large intervals (like if the user is typing) but if the computer is streaming buffered data could things get out of sync? I hope modern computers are fast enough that there won't be any idle bits in the transmission stream.

  • evanhevanh Posts: 15,916

    @ersmith said:
    Thanks @evanh . That looks quite intriguing. I take it temp2 isn't actually scratch, it needs to preserved across calls,

    Correct.

    and that it should be initialized to $FFFF_FFFF (or will 0 work)?

    Either works. But not random bits.

    I'm also a little concerned about what happens if two bytes are sent with an unusual number of bit periods between them -- it looks like the smart pin buffering will work well if bytes are sent back-to-back or at large intervals (like if the user is typing) but if the computer is streaming buffered data could things get out of sync? I hope modern computers are fast enough that there won't be any idle bits in the transmission stream.

    Yeah, very short breaks (less than 20 bit times) will mess up. As is, it has to be contiguous or have larger breaks. It's very much targeted at key presses. Contiguous streaming will be hard pressed at higher rates but it'll certainly go faster than the old routine.

  • evanhevanh Posts: 15,916

    @ersmith said:
    ... I hope modern computers are fast enough that there won't be any idle bits in the transmission stream.

    Hehe, yes, it's does count on the transmitter having good hardware buffers and/or not getting waylaid part way through.

  • Does FlexSpin still l support rev.A? If so, can I tell it to generate errors if rev.B instructions are used?

  • RaymanRayman Posts: 14,648

    @ersmith I just noticed a difference between getch() and getchar() with regards to the enter key.
    When I googled the difference, one page says getch() is non-standard. So, I guess that makes it OK.
    But, it also says that getchar() is supposed to wait for the enter key. Is that right? Doesn't seem to behave that way...

  • evanhevanh Posts: 15,916
    edited 2021-02-26 03:19

    @TonyB_ said:
    Does FlexSpin still l support rev.A? If so, can I tell it to generate errors if rev.B instructions are used?

    Yep, use flexspin -2a Err, no it doesn't support that option any longer. :(

  • Cluso99Cluso99 Posts: 18,069

    In case the older versions have been replaced on Eric's website, I have many of the older versions if you can find which one you need. I'm sure it's detailed in this thread when RevA support was removed.
    I also have many of the old pnut versions too.

  • roglohrogloh Posts: 5,790
    edited 2021-02-26 05:58

    @evanh said:

    @ersmith said:
    Thanks @evanh . That looks quite intriguing. I take it temp2 isn't actually scratch, it needs to preserved across calls,

    Correct.

    and that it should be initialized to $FFFF_FFFF (or will 0 work)?

    Either works. But not random bits.

    I'm also a little concerned about what happens if two bytes are sent with an unusual number of bit periods between them -- it looks like the smart pin buffering will work well if bytes are sent back-to-back or at large intervals (like if the user is typing) but if the computer is streaming buffered data could things get out of sync? I hope modern computers are fast enough that there won't be any idle bits in the transmission stream.

    Yeah, very short breaks (less than 20 bit times) will mess up. As is, it has to be contiguous or have larger breaks. It's very much targeted at key presses. Contiguous streaming will be hard pressed at higher rates but it'll certainly go faster than the old routine.

    @evanh I like this solution with a small buffer for avoiding missed keyboard presses etc, I wonder if there is a good way to handle the other short break times by hunting for start bits in the residual word. Maybe you could invert (NOT), reverse (REV) and encode (ENCOD) the residual to find the next start bit position and then shift appropriately for the next character. If/when the data wraps 32 bit boundaries however things might get messy.

  • evanhevanh Posts: 15,916
    edited 2021-02-26 06:40

    Yeah, I thought about that but buried my head from it. I might have a nosey after I'm done with the fill functions. EDIT: I fear it'll lead to interrupts and large buffering.

    There's another problem. I've just realised that how I used the old routine often relied on checking for hardware buffer full before calling it. Surprisingly, if no more than three characters for a key press then it'll be just as good, that covers the arrow keys nicely. But for the longer six character strings, the servicing response has to be quick. In this case a lower baud would provide more time.

    In either case the old programs have to also be smartened up to empty the soft buffer. Not sure yet how best to do it ...

  • It might be possible to simply detect and report that there is more data available and notify the caller that there is more data pending when you return a character, so it can continue empty as much as possible each time in a loop and keep it as empty as much as possible. Of course that still depends on the application to do this work and probably also buffer elsewhere.

  • @evanh said:

    @TonyB_ said:
    Does FlexSpin still l support rev.A? If so, can I tell it to generate errors if rev.B instructions are used?

    Yep, use flexspin -2a Err, no it doesn't support that option any longer. :(

    @Cluso99 said:
    In case the older versions have been replaced on Eric's website, I have many of the older versions if you can find which one you need. I'm sure it's detailed in this thread when RevA support was removed.
    I also have many of the old pnut versions too.

    I've searched this thread and FlexProp v5.0.2 should support the rev.A. I have no idea what last version of PNut works. Did Spin2 ever work with rev.A?

    This is all so I can donate my rev.A Eval board to a friend.

  • @TonyB_ said:
    Does FlexSpin still l support rev.A?

    Not officially, but I haven't removed the rev A code, so it may still work (the command line option is "-2a"), I think someone on the forums reported success with it a few weeks ago. You're on your own though if things don't work :).

  • @Rayman said:
    @ersmith I just noticed a difference between getch() and getchar() with regards to the enter key.
    When I googled the difference, one page says getch() is non-standard. So, I guess that makes it OK.
    But, it also says that getchar() is supposed to wait for the enter key. Is that right? Doesn't seem to behave that way...

    Your google results are talking about the default behavior of getchar() on many platforms. But I don't think the C standard requires getchar() to wait for enter. For example on Linux you can put the terminal into raw mode and then getchar() should return as soon as any character it typed. flexprop on P2 is pretty similar to that.

  • evanhevanh Posts: 15,916
    edited 2021-02-27 04:02

    @TonyB_ said:
    I've searched this thread and FlexProp v5.0.2 should support the rev.A. I have no idea what last version of PNut works. Did Spin2 ever work with rev.A?

    Pnut never mixed them. Pre-v33 was revA. v33 onwards is revB/C. Needless to say Chip's Spin2 interpreter never supported revA.

    I've attached a repackaged zip of the final v32j files. The original download contained a lot of FPGA bin files that made it 21 MB. I've stripped all those out.

    EDIT: Corrected from v31 to v32j

Sign In or Register to comment.