#include "dir.bi"
mount "/sd", _vfs_open_sdcard()
chdir "/sd/bas"
let currentdir$="/sd/bas"
close #9: open "nonexistingfile" for input as #9 ' that file doesn't exist
let err=geterr() : print err, strerror$(err) : close #9
chdir "/sd"
let err=geterr() : print err, strerror$(err)
chdir "/sd/bas"
close #9: open "mousetheremin.bas" for input as #9 ' that file exists
let err=geterr() : print err, strerror$(err) : close #9
chdir "/sd"
let err=geterr() : print err, strerror$(err)
generates this output:
( Entering terminal mode. Press Ctrl-] or Ctrl-Z to exit. )
4 No such file or directory
5 Bad file number
0 OK
0 OK
After trying to open the file that doesn't exist, chdir produces error 5. However it seems that it changes the directory - I tried to dir after this "failed" chdir and it listed /sd, not /sd/bas
Opening the file that exists restores the normal operation, chdir returns 0 as expected.
Trying to chdir to non existent path generates the error code 16 (function not implemented) that is misleading. Should be "directory doesn't exist" or "path doesn't exist"
I also managed to generate error code 1, but cannot reproduce this now. I managed to got error #1 while trying to delete a file that doesn't exist.
The Basic filesystem related stuff lacks mkdir. 'kill' does rmdir too, but I don't know how to make a new one. For the interpreter's purpose I imported mkdir from C.
There's something fishy with SD mounting I'm getting in recent tests. Not sure what I'm looking at just yet but, without power down, it seems to alternate between no problem and failed card init on each reboot of the Prop2.
Preliminary experimenting is revealing only that the SD card is reporting as non-HC v2.0 card type (CCS bit of OCR register not set). Needless to say it is not handled well given these are all HC capable SD cards.
EDIT: Oops, looks like it might just be one card, I thought I'd tried a second one already but maybe I hadn't ... damn, yeah, just one of my SD cards has this behaviour. It's a Sandisk Extreme 64G SDXC ...
A Kinston Canvas Select Plus 64G SDXC is fine. A Samsung Evo Plus 128G SDXC is fine. An Adata 16G SDHC is fine. And a Sandisk Extreme 32G SDHC is also fine.
EDIT2: I've worked out that each Prop2 reset is also a successive SD boot attempt by the ROM ...
And pressing the Eval Board reset button between each reboot from loadp2 results in 100% failures of the test code instead of the 50% when using loadp2 alone.
I have on,on,off,off switches on EC32 and no problems with SD. It is "serial, then flash" It is a 32 GB Sandisk. I also tested 64GB Sandisk Ultra that also seems to work OK with the EC32 and the Basic interpreter.
The interpreter doesn't work on an Eval now, but when it worked, I also had no problem with the card access. I have to restore the Eval support (4bit video driver has to be updated)
@pik33 said:
Do you have SD boot enabled via switches?
It's implicit when an SD card is present. The card is checked for a valid FAT32 boot file before serial download occurs. If valid then the SD card is booted instead.
It is SDXC, white and gray colors with SDXC written on it. 64 GB has to be SDXC. I formatted it to FAT32 using Linux tools. I also have a 128 GB at home, to be tested
@pik33 said:
The manual says if there is a pullup on P61, P60 is ignored. There should be this:
Serial window of 100ms, then SPI flash.
If SPI flash fails then serial window of 60s.
Is the manual not correct and SD boot attempt always overrides the P61 pullup ??
Intriguing, another two variations when selecting pull-up on P59:
- Almost same behaviour when using just loadp2 repeatedly, the difference is the number of ACMD41 attempts is 9 instead of 3 for successful tests. This could be explained by the ROM boot no longer querying the SD card.
- Opposite behaviour of when pressing the reset button between loadp2 reloads. Now it is 100% success instead of 100% fail.
@pik33 said:
It is SDXC, white and gray colors with SDXC written on it. 64 GB has to be SDXC. I formatted it to FAT32 using Linux tools. I also have a 128 GB at home, to be tested
@ersmith Trying to convert another giant Arduino code to FlexProp C. Came across an interesting coding scheme that gives an error in FlexProp.
There's a function that wants to take an enumerated list member as a parameter. But, that gives an error.
Had to replace with int to get it to compile. See example below where I changed the last parameter to int to make it work.
int inv_icm20948_set_matrix(struct inv_icm20948* s, const float matrix[9], int sensor) //RJA enum inv_icm20948_sensor sensor)
{
The enum is like this:
/** @brief Sensor identifier for control function
*/
enum inv_icm20948_sensor {
INV_ICM20948_SENSOR_ACCELEROMETER,
INV_ICM20948_SENSOR_GYROSCOPE,
INV_ICM20948_SENSOR_RAW_ACCELEROMETER,
INV_ICM20948_SENSOR_RAW_GYROSCOPE,
This type of usage appears in many places but only this one function gives an error. I think it's probably because it's the only one actually used in this example, but don't know for sure.
Any ideas? I've never seen enum used like this before...
@pik33 said:
It is SDXC, white and gray colors with SDXC written on it. 64 GB has to be SDXC. I formatted it to FAT32 using Linux tools. I also have a 128 GB at home, to be tested
Try this tester. Need to run it multiple times.
Run this 5 times, results are not exactly the same, but similar. 64GB Sandisk Ultra
Run #1
( Entering terminal mode. Press Ctrl-] or Ctrl-Z to exit. )
clkfreq = 40000000 clkmode = 0x100071b
mount: OK
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 818 kB/s
Read 100000 of 100000 bytes at 1100 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 890 kB/s
Read 100000 of 100000 bytes at 1094 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 896 kB/s
Read 100000 of 100000 bytes at 1101 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 895 kB/s
Read 100000 of 100000 bytes at 1101 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 979 kB/s
Read 200000 of 200000 bytes at 1111 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 973 kB/s
Read 200000 of 200000 bytes at 1112 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 986 kB/s
Read 200000 of 200000 bytes at 1113 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 985 kB/s
Read 200000 of 200000 bytes at 1112 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 984 kB/s
Read 200000 of 200000 bytes at 1113 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 637 kB/s
Read 20000 of 20000 bytes at 1063 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 729 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 707 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 717 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 709 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 142 kB/s
Read 2000 of 2000 bytes at 761 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 189 kB/s
Read 2000 of 2000 bytes at 765 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 186 kB/s
Read 2000 of 2000 bytes at 765 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 186 kB/s
Read 2000 of 2000 bytes at 765 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 189 kB/s
Read 2000 of 2000 bytes at 765 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 21 kB/s
Read 200 of 200 bytes at 223 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
run #5
( Entering terminal mode. Press Ctrl-] or Ctrl-Z to exit. )
clkfreq = 40000000 clkmode = 0x100071b
mount: OK
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 953 kB/s
Read 100000 of 100000 bytes at 1099 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 948 kB/s
Read 100000 of 100000 bytes at 1101 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 899 kB/s
Read 100000 of 100000 bytes at 1099 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x28aa0 Randfill ticks = 225069
Written 100000 of 100000 bytes at 930 kB/s
Read 100000 of 100000 bytes at 1101 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 997 kB/s
Read 200000 of 200000 bytes at 1111 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 995 kB/s
Read 200000 of 200000 bytes at 1113 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 996 kB/s
Read 200000 of 200000 bytes at 1113 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 965 kB/s
Read 200000 of 200000 bytes at 1111 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x41140 Randfill ticks = 450069
Written 200000 of 200000 bytes at 979 kB/s
Read 200000 of 200000 bytes at 1111 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 721 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 719 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 710 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 716 kB/s
Read 20000 of 20000 bytes at 1063 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x15220 Randfill ticks = 45069
Written 20000 of 20000 bytes at 200 kB/s
Read 20000 of 20000 bytes at 1065 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 187 kB/s
Read 2000 of 2000 bytes at 765 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 189 kB/s
Read 2000 of 2000 bytes at 765 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 189 kB/s
Read 2000 of 2000 bytes at 765 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 187 kB/s
Read 2000 of 2000 bytes at 761 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x10bd0 Randfill ticks = 4565
Written 2000 of 2000 bytes at 189 kB/s
Read 2000 of 2000 bytes at 761 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 6 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
addr1 = 0x10400 addr2 = 0x104c8 Randfill ticks = 517
Written 200 of 200 bytes at 25 kB/s
Read 200 of 200 bytes at 221 kB/s Matches! :)
That's the difference. I have the flash on. This means the SD is not used for booting, and the SD can be mounted after.
(There is a Basic interpreter that I am now developing in the flash)
No, I've already worked out the ROM's attempts are not making any significant difference. It's all down to the particular model of Sandisk Extreme SD card. I don't yet understand how it's alternating nor what is alternating exactly.
PS: I was glad to see your Sandisk Ultra SDXC card not have an issue.
Next step is dump more of the Extreme's registers to see what else is toggling ... or not, the intermediate mode it gets into probably doesn't support many commands. Maybe just reissuing a CMD0 and starting over is the fix.
@pik33 : the error codes in FlexProp work similarly to how they do in Linux and other POSIX systems: successful system calls do not change the error code. This means geterr should really be called getlasterr; it gets the last error result that happened, no matter how many system calls ago it occured (and then clears the error code).
So to check for errors you'd do something like:
r = chdir(place$)
if r <> 0 then
let err = geterr() : print "chdir error: ", err, strerror$(err)
endif
Not all of the file systems are good at reporting specific errors; sometimes they just return a generic error on an operation, and so we can't always get a sensible error code. I don't know if this is the case for chdir() on FATFS; it could also be a bug in the mapping between DOS error codes and FlexProp's. I'll look into it.
@Rayman said:
@ersmith Trying to convert another giant Arduino code to FlexProp C. Came across an interesting coding scheme that gives an error in FlexProp.
There's a function that wants to take an enumerated list member as a parameter. But, that gives an error.
Had to replace with int to get it to compile. See example below where I changed the last parameter to int to make it work.
Could you tell me exactly what error you're getting? If the parameter originally did include the word enum then it should have worked. However, note that C++ automatically typedefs a lot of things (like enum and struct names) that C does not, which means that C++ code can leave out the enum tag. That is, in C++ you can say:
@Rayman said:
@ersmith Also finding this line doesn't work:
static const uint8_t EXPECTED_WHOAMI[] = { 0xEA }; /* WHOAMI value for ICM20948 or derivative */
Again, you'll have to be a bit more specific -- what error do you get? What's the context? Did the file fail to include <stdint.h> for some reason (that's the file that defines things like uint8_t). It may be that in some systems that file gets automatically included by other files.
@ersmith First, thanks for all of your great tools!
I'm not sure if you're interested in warnings from the Mac compiler anymore but I just updated spin2cpp and rebuilt your tools and got this warning.
mcpp/mcpp_support.c:300:18: warning: 'vsprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use vsnprintf(3) instead. [-Wdeprecated-declarations]
rc = vsprintf( mem_buffer, format, ap);
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdio.h:207:1: note: 'vsprintf' has been explicitly marked deprecated here
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use vsnprintf(3) instead.")
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:215:48: note: expanded from macro '__deprecated_msg'
#define __deprecated_msg(_msg) __attribute__((__deprecated__(_msg)))
^
1 warning generated.
@ersmith said:
@pik33 : the error codes in FlexProp work similarly to how they do in Linux and other POSIX systems: successful system calls do not change the error code. This means geterr should really be called getlasterr; it gets the last error result that happened, no matter how many system calls ago it occured (and then clears the error code).
So to check for errors you'd do something like:
r = chdir(place$)
if r <> 0 then
let err = geterr() : print "chdir error: ", err, strerror$(err)
endif
Not all of the file systems are good at reporting specific errors; sometimes they just return a generic error on an operation, and so we can't always get a sensible error code. I don't know if this is the case for chdir() on FATFS; it could also be a bug in the mapping between DOS error codes and FlexProp's. I'll look into it.
I do exactly this.
Opening a non-existing file gives error 4, as expected.
After this, changing the directory gives error 5, while the directory change is a success
Is it possible that there is a queue or stack of errors and I have to do this :
close #9: open "nonexistingfile" for input as #9 ' that file doesn't exist
do : let err=geterr() : print err, strerror$(err) : loop until err=0
close #9
to clean it before the next file related operation?
Edit: no. I experimented with that, the loop prints endless error 4.
So the workaround is still the same: ignore error code 5 after chdir. If it really failed, it gives error code 16
@pik33 : Are you saying that r = chdir("/sub/dir") is returning a non-zero number when it succeeded? I can't seem to reproduce that. If chdir returns 0 then it succeeded, and there is no need to call geterr() (and indeed the result of geterr() is just a left over error from a previous operation, it is not from the chdir).
I think the error 5 code (EBADF, bad file descriptor) is left over from the close #9 after a failed open #9 earlier in your test program.
mount "/sd", _vfs_open_sdcard()
chdir "/sd"
close #9: open "nonexistingfile" for input as #9
let err=geterr() : print err, strerror$(err) : close #9
let err=geterr() : print err, strerror$(err)
chdir "/sd/bas"
let err=geterr() : print err, strerror$(err)
close #9: open "mousetheremin.bas" for input as #9
let err=geterr() : print err, strerror$(err) : close #9
chdir "/sd"
let err=geterr() : print err, strerror$(err)
produces this:
4 No such file or directory
5 Bad file number
5 Bad file number
0 OK
0 OK
so yes, error 5 is caused by close #9, but then it persists after chdir /sd/bas. That was successful, but err was still 5. The "mousetheremin.bas" exists in /sd/bas, so it opened, and the error=0. Also after chdir to /sd all is OK, error=0
Well, I dunno how much Loadp2 timings play into this mystery with the Sandisk Extreme SDXC card just yet but the problem seems to revolve around the Eval Board's reset circuits. The DTR resetting creates a brownout condition on the common VIO power rail. And that particular SD card model gets upset as a result.
PS: My latest big discovery is that the problem doesn't occur with an Edge Card. So, Pik, your tests won't fail with any SD card then.
We're probably lucky more SD cards aren't throwing tantrums on the Eval Boards.
Attached snapshot shows volt droop on pin P60 (blue trace) of an Eval Board. P60 is one of the pins with a pull-up internal to the SD card. So this effectively shows what's happening to the SD card itself.
Pink trace is VIO volts V5663.
Orange trace is P2_RESN. Looks like it's purely to do with circuit components reset timing. Nothing that software can do unless it makes DTR pulse for one microsecond maybe. That way the smoothing capacitors will hold the power rail up while the regulator restarts.
That geterr persists after chdir is expected. Successful system calls (like a successful chdir) do not change the last error flag. The only exception to this is open, which in BASIC is not a traditional function call.
However, I did notice that geterr itself is not resetting the error indicator, and that is probably a bug. I've changed that in the current github.
After changing geterr to clear the error after reading, Basic's open doesn't report any errors when try to open a file that doesn't exist (geterr is 0 )
The filesystem by default pulls its date/time from the GETCT counter, there's a function to set the offset so that it matches real time, but I forget what it's called.
Comments
This test code
generates this output:
After trying to open the file that doesn't exist, chdir produces error 5. However it seems that it changes the directory - I tried to dir after this "failed" chdir and it listed /sd, not /sd/bas
Opening the file that exists restores the normal operation, chdir returns 0 as expected.
Trying to chdir to non existent path generates the error code 16 (function not implemented) that is misleading. Should be "directory doesn't exist" or "path doesn't exist"
I also managed to generate error code 1, but cannot reproduce this now. I managed to got error #1 while trying to delete a file that doesn't exist.
The Basic filesystem related stuff lacks mkdir. 'kill' does rmdir too, but I don't know how to make a new one. For the interpreter's purpose I imported mkdir from C.
There's something fishy with SD mounting I'm getting in recent tests. Not sure what I'm looking at just yet but, without power down, it seems to alternate between no problem and failed card init on each reboot of the Prop2.
Preliminary experimenting is revealing only that the SD card is reporting as non-HC v2.0 card type (CCS bit of OCR register not set). Needless to say it is not handled well given these are all HC capable SD cards.
EDIT: Oops, looks like it might just be one card, I thought I'd tried a second one already but maybe I hadn't ... damn, yeah, just one of my SD cards has this behaviour. It's a Sandisk Extreme 64G SDXC ...
A Kinston Canvas Select Plus 64G SDXC is fine. A Samsung Evo Plus 128G SDXC is fine. An Adata 16G SDHC is fine. And a Sandisk Extreme 32G SDHC is also fine.
EDIT2: I've worked out that each Prop2 reset is also a successive SD boot attempt by the ROM ...
And pressing the Eval Board reset button between each reboot from loadp2 results in 100% failures of the test code instead of the 50% when using loadp2 alone.
I have on,on,off,off switches on EC32 and no problems with SD. It is "serial, then flash" It is a 32 GB Sandisk. I also tested 64GB Sandisk Ultra that also seems to work OK with the EC32 and the Basic interpreter.
The interpreter doesn't work on an Eval now, but when it worked, I also had no problem with the card access. I have to restore the Eval support (4bit video driver has to be updated)
Do you have SD boot enabled via switches?
It's implicit when an SD card is present. The card is checked for a valid FAT32 boot file before serial download occurs. If valid then the SD card is booted instead.
The manual says if there is a pullup on P61, P60 is ignored. There should be this:
Is the manual not correct and SD boot attempt always overrides the P61 pullup ??
Is it SDHC or SDXC?
It is SDXC, white and gray colors with SDXC written on it. 64 GB has to be SDXC. I formatted it to FAT32 using Linux tools. I also have a 128 GB at home, to be tested
Intriguing, another two variations when selecting pull-up on P59:
- Almost same behaviour when using just loadp2 repeatedly, the difference is the number of ACMD41 attempts is 9 instead of 3 for successful tests. This could be explained by the ROM boot no longer querying the SD card.
- Opposite behaviour of when pressing the reset button between loadp2 reloads. Now it is 100% success instead of 100% fail.
PS: I've not had Flash (P61) on.
Try this tester. Need to run it multiple times.
@ersmith Trying to convert another giant Arduino code to FlexProp C. Came across an interesting coding scheme that gives an error in FlexProp.
There's a function that wants to take an enumerated list member as a parameter. But, that gives an error.
Had to replace with int to get it to compile. See example below where I changed the last parameter to int to make it work.
The enum is like this:
This type of usage appears in many places but only this one function gives an error. I think it's probably because it's the only one actually used in this example, but don't know for sure.
Any ideas? I've never seen enum used like this before...
Run this 5 times, results are not exactly the same, but similar. 64GB Sandisk Ultra
Run #1
run #5
That's all successes. Good.
A fail looks like this:
I also have been debugging with output like this for a success:
And this for a fail:
@ersmith Also finding this line doesn't work:
static const uint8_t EXPECTED_WHOAMI[] = { 0xEA }; /* WHOAMI value for ICM20948 or derivative */
That's the difference. I have the flash on. This means the SD is not used for booting, and the SD can be mounted after.
(There is a Basic interpreter that I am now developing in the flash)
No, I've already worked out the ROM's attempts are not making any significant difference. It's all down to the particular model of Sandisk Extreme SD card. I don't yet understand how it's alternating nor what is alternating exactly.
PS: I was glad to see your Sandisk Ultra SDXC card not have an issue.
Next step is dump more of the Extreme's registers to see what else is toggling ... or not, the intermediate mode it gets into probably doesn't support many commands. Maybe just reissuing a CMD0 and starting over is the fix.
@pik33 : the error codes in FlexProp work similarly to how they do in Linux and other POSIX systems: successful system calls do not change the error code. This means
geterr
should really be calledgetlasterr
; it gets the last error result that happened, no matter how many system calls ago it occured (and then clears the error code).So to check for errors you'd do something like:
Not all of the file systems are good at reporting specific errors; sometimes they just return a generic error on an operation, and so we can't always get a sensible error code. I don't know if this is the case for chdir() on FATFS; it could also be a bug in the mapping between DOS error codes and FlexProp's. I'll look into it.
Could you tell me exactly what error you're getting? If the parameter originally did include the word
enum
then it should have worked. However, note that C++ automatically typedefs a lot of things (like enum and struct names) that C does not, which means that C++ code can leave out theenum
tag. That is, in C++ you can say:whereas in C (and FlexC) you have to say:
Again, you'll have to be a bit more specific -- what error do you get? What's the context? Did the file fail to include
<stdint.h>
for some reason (that's the file that defines things likeuint8_t
). It may be that in some systems that file gets automatically included by other files.@ersmith First, thanks for all of your great tools!
I'm not sure if you're interested in warnings from the Mac compiler anymore but I just updated spin2cpp and rebuilt your tools and got this warning.
I do exactly this.
Opening a non-existing file gives error 4, as expected.
After this, changing the directory gives error 5, while the directory change is a success
Is it possible that there is a queue or stack of errors and I have to do this :
to clean it before the next file related operation?
Edit: no. I experimented with that, the loop prints endless error 4.
So the workaround is still the same: ignore error code 5 after chdir. If it really failed, it gives error code 16
@pik33 : Are you saying that
r = chdir("/sub/dir")
is returning a non-zero number when it succeeded? I can't seem to reproduce that. Ifchdir
returns 0 then it succeeded, and there is no need to callgeterr()
(and indeed the result ofgeterr()
is just a left over error from a previous operation, it is not from thechdir
).I think the error 5 code (EBADF, bad file descriptor) is left over from the
close #9
after a failedopen #9
earlier in your test program.This
produces this:
so yes, error 5 is caused by close #9, but then it persists after chdir /sd/bas. That was successful, but err was still 5. The "mousetheremin.bas" exists in /sd/bas, so it opened, and the error=0. Also after chdir to /sd all is OK, error=0
Well, I dunno how much Loadp2 timings play into this mystery with the Sandisk Extreme SDXC card just yet but the problem seems to revolve around the Eval Board's reset circuits. The DTR resetting creates a brownout condition on the common VIO power rail. And that particular SD card model gets upset as a result.
PS: My latest big discovery is that the problem doesn't occur with an Edge Card. So, Pik, your tests won't fail with any SD card then.
We're probably lucky more SD cards aren't throwing tantrums on the Eval Boards.
Attached snapshot shows volt droop on pin P60 (blue trace) of an Eval Board. P60 is one of the pins with a pull-up internal to the SD card. So this effectively shows what's happening to the SD card itself.
Pink trace is VIO volts V5663.
Orange trace is P2_RESN. Looks like it's purely to do with circuit components reset timing. Nothing that software can do unless it makes DTR pulse for one microsecond maybe. That way the smoothing capacitors will hold the power rail up while the regulator restarts.
What might be best is everyone removing the resistor from RESN that controls the regulator. Then it'll be the same as the Edge Cards.
EDIT: Correction, move the resistor from R802 position to the empty R801 position.
EDIT2: Yep, moving R802 to R801 fixes it. To be precise, I threw out the microscopic resistor and blobbed a fine strand of wire onto R801 position.
That geterr persists after chdir is expected. Successful system calls (like a successful chdir) do not change the last error flag. The only exception to this is
open
, which in BASIC is not a traditional function call.However, I did notice that
geterr
itself is not resetting the error indicator, and that is probably a bug. I've changed that in the current github.I upgraded the compiler and got this:
C:/Users/Piotr/Downloads/flexprop-6.4.0/flexprop/include/libsys/mkdir.c:22: error: Bad number of parameters in call to mkdir: expected 2 found 1
The error line is
r = (*v->mkdir)(name);
The called function is declared as
int (*mkdir)(const char *name, mode_t mode);
so 'mode' is missing there
I added 0 there, it seems to work
After changing geterr to clear the error after reading, Basic's open doesn't report any errors when try to open a file that doesn't exist (geterr is 0 )
@pik33 : thank you for the bug reports. Both should be fixed now in the latest github source code.
A question: what if I add a RTC to the P2 system? Can I tell the filesystem driver the current time that I can read from the RTC?
The filesystem by default pulls its date/time from the GETCT counter, there's a function to set the offset so that it matches real time, but I forget what it's called.