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

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

1117118119120122

Comments

  • ersmithersmith Posts: 6,067

    @evanh I'm sorry, I was mistaken about ioctl, it isn't hooked all the way up -- that is, an ioctl() on a file doesn't get passed through to the disk :(

    However, you can do something like the following:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdint.h>
    #include <sys/vfs.h>
    #include <fcntl.h>
    
    int main() {
        int r;
        FILE *raw_device = _sdmm_open(61, 60, 59, 58);
    
        if (!raw_device) {
            printf("Unable to open SD card\n");
            return 1;
        }
        /* strictly speaking we don't need to mount to access the device layer,
           but we probably will want to eventually */
        mount("/sd", _vfs_open_fat_handle(raw_device));
        uint8_t *buff = __builtin_alloca(20);    // auto-frees upon return
        errno = 0;
        r = raw_device->ioctl(raw_device, 0, buff);    // Attempting to trigger a CTRL_SYNC in the SD device driver
        printf(" ioctl %d (%d): %s\n", r, errno, strerror(errno));
        return 0;
    }
    

    There was a typo in the declaration of _vfs_open_fat_handle in include/sys/vfs.h (it was looking in the 9p file system instead of fatfs). That's fixed in the current github, or you can change it yourself in your local copy.

  • evanhevanh Posts: 16,016
    edited 2024-11-22 16:04

    Yes! I have the "SYNC" printing. Thank you.

    Ah, I see device init is called even before mounting now.

    I'm way past bedtime. Zzzz

  • RaymanRayman Posts: 14,721

    @ersmith Do you have an opinion on the best name for a file to hold pin and clock settings and such in?

    I've been using Platform.h (copied from Arduino). I see @Wuerfel_21 uses config.spin2 a lot (exclusively?).

    Maybe you have a different/better option/opinion?

  • evanhevanh Posts: 16,016

    Sounds good to me. The name doesn't really matter, afaics.

  • ersmithersmith Posts: 6,067

    @Rayman said:
    @ersmith Do you have an opinion on the best name for a file to hold pin and clock settings and such in?

    I've been using Platform.h (copied from Arduino). I see @Wuerfel_21 uses config.spin2 a lot (exclusively?).

    Maybe you have a different/better option/opinion?

    Personally I like "config.*" as I think it's a bit more common. But really I don't have any more insight into this than anyone else :) so if you prefer Platform.h then go ahead.

  • Don't assume there's some motivated idea behind naming it "config.spin". I also have "platform.spin"s in other projects.

  • evanhevanh Posts: 16,016
    edited 2024-11-29 07:24

    Eric,
    Specifying the size of Fcache in the compile command is driving me bats.
    Can there be two defaults for size of Fcache? One for byte-coded and one for native.

    EDIT: Or add a compile warning that the Pasm doesn't fit in the available size. This would be perfectly fine. Whereas the current runtime crashes aren't a great reminder.
    EDIT2: Err, too tired when I posted I think. You've probably got a warning already. The problem I have is I use an undeclared block of cogRAM for a temporary working buffer: 520 bytes for data block + CRC, plus the actual Fcache'd supporting Pasm code to work on it and manage the streamer in parallel. I'm simply counting on Fcache being big enough.

  • roglohrogloh Posts: 5,833

    @ersmith , I just encountered a bug in my code which might be something to be aware of regarding alignment in flexspin.

    Not sure if most people are in the habit of automatically putting alignl instructions before code in DAT blocks, but I'm not one of them. I had two DAT blocks in my code and couldn't get the code to work because the prior DAT block did not end on a long so the next one wasn't aligned and would crash when trying to start the COG code. I wonder if it makes sense to generate a warning if any ORG 0 or plain ORG does not already align on a long boundary in HUB RAM so this won't occur and people can align it. Or maybe force long re-alignment on all ORG's (might be tricky to do if some HUB labels are defined prior that would need to be adjusted to it as well, so a warning is probably safer).

    Here's the offending code. Run it with and without the ALIGNL directive enabled to see what I mean. Was not so bad to locate this issue when the DATs were directly following each other, but sometimes multiple DAT blocks are separated widely inside the source making a problem like this hard to find.

    I tested with Version 7.0.0-beta-v6.9.7-65-g3914edfd Compiled on: Sep 9 2024 in case that matters.

  • Wuerfel_21Wuerfel_21 Posts: 5,097
    edited 2024-11-28 01:45

    @rogloh ORG does force long-alignment. Your problem is that you define the label before the ORG, so when alignment is inserted, your label no longer points correctly at the first insn. You need to define it after the ORG.

    (Does COGINIT on P2 even need to be aligned in the first place?)

  • roglohrogloh Posts: 5,833

    @Wuerfel_21 said:
    @rogloh ORG does force long-alignment. Your problem is that you define the label before the ORG, so when alignment is inserted, your label no longer points correctly at the first insn. You need to define it after the ORG.

    (Does COGINIT on P2 even need to be aligned in the first place?)

    But I thought if you put it after the ORG, the label is not a hub RAM address and can't be used by COGINIT, right? Actually just tried it and seems flex is smarter than me, it must convert it for use from SPIN2.

  • Wuerfel_21Wuerfel_21 Posts: 5,097
    edited 2024-11-28 02:11

    @rogloh said:

    @Wuerfel_21 said:
    @rogloh ORG does force long-alignment. Your problem is that you define the label before the ORG, so when alignment is inserted, your label no longer points correctly at the first insn. You need to define it after the ORG.

    (Does COGINIT on P2 even need to be aligned in the first place?)

    But I thought if you put it after the ORG, the label is not a hub RAM address and can't be used by COGINIT, right? Actually just tried it and seems flex is smarter than me, it must convert it for use from SPIN2.

    If you do @label you always get the hub address.
    Without the @ and just the name, you get:

    • In Spin code: The data at the address (by default long-sized, can override it with long/word/byte on the same line)
    • In DAT code:
      • If the label was defined in ORG mode: The cog/lut-space address
      • If the label was defined in ORGH mode: The hub address.

    Note that hub addresses in DAT space are all relative to the object's DBASE, so they need to be offset using the @@ operator (pure PASM programs do get absolute addresses). Flexspin also has the triple @@@ operator that gets the real address (but can't be used in totally arbitrary expressions)

  • roglohrogloh Posts: 5,833
    edited 2024-11-28 02:29

    I do wish I could remember all these addressing rules. 😫 Problem is if you don't code everyday you start to forget over time. The mind is a DRAM.

  • evanhevanh Posts: 16,016

    A question regarding Fcache: I note that all explicit RET instructions in the pasm source gets replaced with a relative branch to the final return code that is tacked on at the end. But this final code is just a single return itself. I'm guessing the branches aren't entirely required. It could be optimised to allow the specified returns to action directly, right?

  • ersmithersmith Posts: 6,067

    @evanh said:
    Eric,
    Specifying the size of Fcache in the compile command is driving me bats.
    Can there be two defaults for size of Fcache? One for byte-coded and one for native.

    EDIT: Or add a compile warning that the Pasm doesn't fit in the available size. This would be perfectly fine. Whereas the current runtime crashes aren't a great reminder.
    EDIT2: Err, too tired when I posted I think. You've probably got a warning already. The problem I have is I use an undeclared block of cogRAM for a temporary working buffer: 520 bytes for data block + CRC, plus the actual Fcache'd supporting Pasm code to work on it and manage the streamer in parallel. I'm simply counting on Fcache being big enough.

    The size overflow error handling had some holes, which I hope should be fixed now in github. Also, why not explicitly declare the block? Ah, I see: long 0[32] wasn't working in inline assembly. That's also fixed now in github.

  • ersmithersmith Posts: 6,067

    @evanh said:
    A question regarding Fcache: I note that all explicit RET instructions in the pasm source gets replaced with a relative branch to the final return code that is tacked on at the end. But this final code is just a single return itself. I'm guessing the branches aren't entirely required. It could be optimised to allow the specified returns to action directly, right?

    Yeah, they're converted to branches for the case where the asm goes into HUB, but for FCACHE they should probably be left alone as RET instructions.

  • evanhevanh Posts: 16,016
    edited 2024-12-01 00:26

    @ersmith said:
    ... Also, why not explicitly declare the block? ...

    Well, I wasn't really wanting Fcache to copy a blank array into cogRAM when the pasm code itself will immediately overwrite it. And it's not so small: long 0[138] will be needed all up.
    128 longwords for the 512 byte data block, 2 for the CRC nibbles, and 8 more for the setset parameters.

  • evanhevanh Posts: 16,016
    edited 2024-12-01 00:31

    [babbling too much]

  • evanhevanh Posts: 16,016

    My latest adventure is to attempt to make an equivalent file speed tester still written in Spin2 but using the object "libc.spin2" for file management instead of FSRW or FAT32FS. Is there a way to access C's errno global variable? And is there an equivalent to __builtin_alloca() for Spin?

    PS: I note the newer card init support isn't there yet so I've reverted the legacy API.

  • ersmithersmith Posts: 6,067

    @evanh said:
    My latest adventure is to attempt to make an equivalent file speed tester still written in Spin2 but using the object "libc.spin2" for file management instead of FSRW or FAT32FS. Is there a way to access C's errno global variable?

    There are functions _geterror() and _seterror(), and at a lower level there's int *_geterrnoptr() which returns a pointer to errno. I noticed these weren't exposed in libc.a so I've just updated github to have them.

    And is there an equivalent to __builtin_alloca() for Spin?

    All the __builtin_ functions work in any language (at least, in FlexSpin; if you're asking if PNut has some equivalent then I don't think so.)

    PS: I note the newer card init support isn't there yet so I've reverted the legacy API.

    ? I don't quite understand this. Is there some function missing from libc.a?

  • evanhevanh Posts: 16,016

    @ersmith said:
    There are functions _geterror() and _seterror(), and at a lower level there's int *_geterrnoptr() which returns a pointer to errno. I noticed these weren't exposed in libc.a so I've just updated github to have them.

    Ah, I hadn't learnt those. I'd always found 'errno' is just there and used it.

    All the __builtin_ functions work in any language (at least, in FlexSpin; if you're asking if PNut has some equivalent then I don't think so.)

    I'll try some naming combinations ...

    PS: I note the newer card init support isn't there yet so I've reverted the legacy API.

    ? I don't quite understand this. Is there some function missing from libc.a?

    Yes ... _sdmm_open() and _vfs_open_fat_handle()

  • ersmithersmith Posts: 6,067

    @evanh said:

    ? I don't quite understand this. Is there some function missing from libc.a?

    Yes ... _sdmm_open() and _vfs_open_fat_handle()

    Oh, right. Thanks, I've added them now.

  • evanhevanh Posts: 16,016
    edited 2024-12-06 16:45

    @ersmith said:

    @evanh said:

    ? I don't quite understand this. Is there some function missing from libc.a?

    Yes ... _sdmm_open() and _vfs_open_fat_handle()

    Oh, right. Thanks, I've added them now.

    Five typos in two lines! You're tired! :)

    EDIT: Hmm, or maybe just three typos. Changing to _FILE * doesn't work, but FILE * won't even compile. I get this:
    include/libc.a:12: error: syntax error, unexpected '*', expecting __fromfile or '{'

  • ersmithersmith Posts: 6,067

    @evanh Sorry, yes, I am tired. It does compile now at least.

  • evanhevanh Posts: 16,016
    edited 2024-12-07 01:46

    Huh, _FILE * works now. Dunno what I did wrong last night.

    I do still get a warning that doesn't make any sense to me. Not only that, but the warning also moves around if I remove the offending line as reported in the warning. It first appeared as one of my additions but when I then removed the offending line or even the whole file, which is optional, the warning then switches to this:
    include/filesys/fatfs/fatfs_vfs.c:96: warning: mixing pointer and integer types in return: expected pointer to _struct__vfs but got int

    Again, the offending line is clearly not the problem: return _seterror(EBADF);

    I guess time for some bisecting, I've long forgotten how ...

    PS: This only occurs when I use OBJ c: "libc.spin2". If I build the C edition of the same tester then there is no warnings. Since I've not used this feature before, maybe the issue has been around a long time.
    Compiled with flexspin --fcache=256 -g -q -l -2 -D _DEBUG_SDMM -D _BAUD=2000000 sdfat-speedtest.spin2

  • evanhevanh Posts: 16,016
    edited 2024-12-08 04:53

    I've documented how to add a fresh block driver to fatfs

    Add new block driver in include/filesys/fatfs/block
    
    In file include/filesys/sdfatfs/fatfs_vfs.c, duplicate device open function _sdmm_open()
    and name it suitable match of new driver name, eg: _sdsd_open()
    
    Edit the new device open function, eg:
        Assign the driver file:
            struct __using("filesys/block/sdsd.cc") *SDSD;
        Search and replace:
            SDMM -> SDSD
        Update arguments:
            _sdsd_open(int pclk, int pcmd, int pdat0, int ppwr, int pled)
        Matching debug print:
            __builtin_printf("sdsd_open: using pins: %d %d %d %d %d\n", pclk, pcmd, pdat0, ppwr, pled);
        Matching disk_setpins():
            r = FFS->disk_setpins(drv, pclk, pcmd, pdat0, ppwr, pled);
        Update "pmask" for pin allocation differences:
            pmask = (1ULL << pclk) | (1ULL << pcmd) | (7ULL << pdat0);
            if( ppwr >= 0 )    // optional SD slot power switch
                pmask |= 1ULL << ppwr;
            if( pled >= 0 )    // optional SD slot activity LED
                pmask |= 1ULL << pled;
    

    EDIT: Details refined

  • pik33pik33 Posts: 2,382
    edited 2024-12-09 12:43

    Something wrong happened with varptr between 6.9.10 and 7.0.0 beta.

    My Basic interpreter compiles and works with 6.9.10 while hangs up compiled with 7.0.0 beta.

    The problem seems to be varptr. I call this at the start of the main program : kbm.mouse_set_outptr(varptr(v.spr1ptr)+16*12+4)

    to set the mouse cursor data pointer for the USB driver

    While this works with 6.9.10 and older, on 7.0.0 this varptr returns 0.

    Maybe I can find the commit that made the change.

    Edit: it seems the first "bad" commit is 280d8e0 - implement ~ and ~~ for structures
    The last "good" commit is cb2ee72 - Suppress some asm warnings when building compiler output

  • Bizarre that that commit would break it, it only contains spin parser changes.

  • pik33pik33 Posts: 2,382
    edited 2024-12-09 19:11

    I don't know why, but after 280d8e0 nothing works for this version of my Basic interpreter. Varptr looking for address of variable in another (Spin) object returned 0. The variable is a long[54] (array). When I initialized its first element by spr1.ptr(0)=2000 I got non-zero value from varptr, but it was still wrong (small integer).

    The temporary solution was simple, I have now the cb2ee72 commit as a compiler.

    I have yet to look for bugs in my video driver, maybe Spin parser change+Spin bug made this mess. And I have to test this on simple examples (a simple Spin object with several variables, a Basic simple main program using varptr) and check what the call to varptr() returns.

  • ersmithersmith Posts: 6,067

    @pik33 is your source code available somewhere?

  • pik33pik33 Posts: 2,382
    edited 2024-12-10 08:16

    Yes, https://github.com/pik33/P2-Retromachine-Basic. The newest version that I am testing is https://github.com/pik33/P2-Retromachine-Basic/blob/main/basic0492.bas. Needs EC32, HDMI at 0 and USB at 16 and SD card with /bas, /bin and /media folders on it. Copy the /media folder from the repository, as it has waveform definitions fot the audio subsystem, /bas and /bin may be empty. /bas is the default directory to load/save; you can place examples there. /bin is the default place for P2 binaries that you can start from the interpreter using brun command.

    The documentation: https://github.com/pik33/P2-Retromachine-Basic/blob/main/The P2 Retromachine Basic 0.49 documentation.pdf - needs to be synchronized with the current version

    The symptoms of non-working binary is mouse cursor not moving and keyboard not responding or delayed. Working binary simply works.

Sign In or Register to comment.