@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.
@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.
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.
@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.
@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?)
@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_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)
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?
@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.
@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.
@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.
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.
@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?
@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?
? 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 '{'
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
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
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.
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.
Comments
@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:
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.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
@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?
Sounds good to me. The name doesn't really matter, afaics.
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.
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.
@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.
@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:
long
/word
/byte
on the same line)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)
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.
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?
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.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.
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.
[babbling too much]
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.
There are functions
_geterror()
and_seterror()
, and at a lower level there'sint *_geterrnoptr()
which returns a pointer toerrno
. I noticed these weren't exposed in libc.a so I've just updated github to have them.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 don't quite understand this. Is there some function missing from libc.a?
Ah, I hadn't learnt those. I'd always found 'errno' is just there and used it.
I'll try some naming combinations ...
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, butFILE *
won't even compile. I get this:include/libc.a:12: error: syntax error, unexpected '*', expecting __fromfile or '{'
@evanh Sorry, yes, I am tired. It does compile now at least.
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
I've documented how to add a fresh block driver to fatfs
EDIT: Details refined
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.
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.
@pik33 is your source code available somewhere?
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.