Do you see the "hiddenSectors" offset? You'll need to somehow undo that offset when you want sector level access. You'll break the FAT file system if you just remove it however. The "hiddenSectors" value is the offset from the MBR to the file system partition. You'll also need to feed a different address to the "cardBlockAddress" value.
You'll want to take into account that you need to mount the file system first and all the other regular code I have running in the background is still going. So, don't do anything really weird. Also, the functions still abort...
You'll want to take into account that you need to mount the file system first and all the other regular code I have running in the background is still going. So, don't do anything really weird. Also, the functions still abort...
Hello Kye,
Sorry, its me again. In my test code, it worked beautifully (with only 1 uSD socket) but when I insert it into my main code & board (with 4 uSD sockets), it hang at readLowLevelSector. Is the problem due to launching more than 1 instances of SD-MMC_FATEngine.spin?
Um... if you have literally separate included versions of the SD card driver (i.e differently named files).... they shouldn't care about each other.
If you made two instances with the same driver then you could have problems. So... how are you using two instances of the same driver file? You're by passing the locking mechanism with direct access.
Basically, this includes the driver 4 times. But, the master and slave versions are literally completely separate. THIS copies the entire code twice, be aware.
Then you can use the trick you are trying to do by restarting the slave driver and moving it around on the pins.
Try out this hacked version. I think it should work. I put in all the code for the function calls so that the locking is not bypassed.
Basically, this includes the driver 4 times. But, the master and slave versions are literally completely separate. THIS copies the entire code twice, be aware.
Oh, I see. Got it. I'm going to test this right away... Thanks a lot, Kye!
NOTE: You need to mount the file system like regular.
Thanks Kye.
I've tested & the result is the same. I've placed some debugging statements outputting to PST. It still hangs at readLowLevelSector() and I don't know why. I've tried increasing the stack all the way to 1_024 but that didn't help. I'm attaching the uSD controller object file.
PST OUTPUT
======================================
In LaunchX4uSDControllerCog Debug Mode
======================================
uSD Socket [0] is : 1
uSD Socket [1] is : 1
uSD Socket [2] is : 0
uSD Socket [3] is : 0
Total Sectors for Card [0] is : 999920
Total Sectors for Card [1] is : 3910976
Total Sectors for Card [2] is : 0
Total Sectors for Card [3] is : 0
Inside Copying Loop ...
Inside curSector =< totalSector ...
Before readLowLevelSector from Master ...
Master Drive
============
Disk Signature : 0
Volume ID : -153891637
Parition Type: FAT16
Volume Label : NO NAME
Total Sectors : 999920
Client Drive 1
==============
Disk Signature : 0
Volume ID : -1470471069
Parition Type: FAT16
Volume Label : NO NAME
Total Sectors : 3910976
curSector Value is : 0
I can access both the Master & Client1 drive but it didn't display ""After readLowLevelSector of Master ..." after the readLowLevelSector().
Also, if you have some time. Setup abort handling in your code to print any aborted errors. Its pretty much a requirement with my driver. If you aren't printing abort errors or handling them then it's very hard to debug.
Also, if you have some time. Setup abort handling in your code to print any aborted errors. Its pretty much a requirement with my driver. If you aren't printing abort errors or handling them then it's very hard to debug.
That's right.
======================================
In LaunchX4uSDControllerCog Debug Mode
======================================
uSD Socket [0] is : 1
uSD Socket [1] is : 1
uSD Socket [2] is : 0
uSD Socket [3] is : 0
Total Sectors for Card [0] is : 999920
Total Sectors for Card [1] is : 3910976
Total Sectors for Card [2] is : 0
Total Sectors for Card [3] is : 0
Inside Copying Loop ...
Inside curSector =< totalSector ...
Before readLowLevelSector from Master ...
Master Drive
============
Disk Signature : 0
Volume ID : -153891637
Parition Type: FAT16
Volume Label : NO NAME
Total Sectors : 999920
Client Drive 1
==============
Disk Signature : 0
Volume ID : -1470471069
Parition Type: FAT16
Volume Label : NO NAME
Total Sectors : 3910976
curSector Value is : 0
Debugging: Disk IO Error
After readLowLevelSector of Master ... readSectorBlockBuffer:
Hmm ... don't get it, I could access Master drive just before the function. I've tried swapping with other the cards but result still the same...
It seems like you want to have 4 uSD cards at the same time. It that is the case then you need to have 4 separately named versions of the driver.
... Yeah, I know, not enough memory for that. Including the same named driver file more then once just allows you to have more than one file open. I.e. a file open per included version of the driver.
---
So, do you even need the file system layer? You could just decapitate the file system part from the block driver.
Also... I think you might have an easier time just using FSRW's block driver. It will allow you to do what you want more easily. I recommend that you use it. You'll get much faster transfer speeds also.
You're right. I was holding that as an option for the sector-copy function. I seems to got a work around (including commenting out the lockFileSystem()) but, yeah, the speed does suffers a lot. I'll test a little more before switching to FSRW.
See the fat.partitionError function. It holds the last error encountered. See the defined constants at the top of the file for all the errors. This is also mentioned in the Parallax semiconductor an006 write up.
Hi Kye, can I suggest an addition to the FAT engine?
I think that having an SD card is an excellent place to store logging data for any project and..
This FAT driver already has all the needed stuff like getting date and time for a timestamp and of course handling the file writing.
A function like
fat.log(Severity, Message)
With
- "Severity" being a constant enumeration (Information/Warning/Error/Critical/etc)
- "Message" a user defined text string
This function would append in a user defined (or fixed) file a whole line of text that includes at least the following fields separated with a defined char like space/commas/tabs/etc
- timestamp
- cog number (optional, but would help))
- Severity in clear text
- message
I can do it myself but surely You will do it faster and I think it would benefit everyone. What do you think?
Such a logging feature does not belong in a file system API.
For example it is possible a user may want to redirect log messages to a serial or network link for recording elsewhere. Or just stream them to a raw fash chip. Better to have a logging API at a higher level that may make use of a file system if wanted.
Such a logging feature does not belong in a file system API.
For example it is possible a user may want to redirect log messages to a serial or network link for recording elsewhere. Or just stream them to a raw fash chip. Better to have a logging API at a higher level that may make use of a file system if wanted.
Heater, I agree on a theoretical basis, however given the limited resources on a Propeller platform I still think a little deviation from a pure subsystem encapsulation is worth the price for the benefit.
BTW, have you seen or have a logging API with the functions you described? For SPIN?
I agree that when resources are constrained perhaps some architectural niceties have to go out the window.
However making a logging system as you describe probably does not take much more space than mixing it into the file system where it will actually waste space for most users who don't use that feature.
I found a solution. Replace every instance of fat.openfile(stringptr,"R") with a call to a different routine eg OpenFileRead which then displays both the error message and the filename (so you can debug it).
PUB OpenFileRead(stringptr) ' open a file for reading and display a message if it fails
result := \fat.openfile(stringptr,"R")
if fat.partitionerror <> 0 ' failed to find the file
propfont_string(stringptr) ' print the filename
propfont_string(result) ' print the error message
repeat ' stop the program
Oh and I found the version that has no RTC and since I don't have a clock I've replaced the code with that version which saves some space.
In your first case you have "fat.openfile(...)" in the second case you have "\fat.openfle(...)". Note the "\".
If openfile fails it aborts. If the abort is not caught by adding that slash to the call then the program aborts totally and looks like a hang.
Comments
Do you see the "hiddenSectors" offset? You'll need to somehow undo that offset when you want sector level access. You'll break the FAT file system if you just remove it however. The "hiddenSectors" value is the offset from the MBR to the file system partition. You'll also need to feed a different address to the "cardBlockAddress" value.
You'll want to take into account that you need to mount the file system first and all the other regular code I have running in the background is still going. So, don't do anything really weird. Also, the functions still abort...
Thank you. Always appreciates your support.
I'll test this first thing tomorrow morning.
Thanks a lot Kye! It worked for me. See you guys @ Parallax Expo next month.
Hello Kye,
Sorry, its me again. In my test code, it worked beautifully (with only 1 uSD socket) but when I insert it into my main code & board (with 4 uSD sockets), it hang at readLowLevelSector. Is the problem due to launching more than 1 instances of SD-MMC_FATEngine.spin?
Thanks a lot.
If you made two instances with the same driver then you could have problems. So... how are you using two instances of the same driver file? You're by passing the locking mechanism with direct access.
Thanks Kye. Let me detail out the project but if you think its better I start another thread so as not to hijack this one, let me know.
I'm working on our small product called Portable MicroSD X4 Duplicator (<- embedded video link). Initially, I wrote:
and I only load those whose cards are inserted:
but when I realise the problem with readLowLevelSector(), I changed to:
but I guess it makes no difference since the result was the same.
Since I would read from Master & write to Clientx, do I need to care about this one?
Thanks a lot.
So... you should have this...
Basically, this includes the driver 4 times. But, the master and slave versions are literally completely separate. THIS copies the entire code twice, be aware.
Then you can use the trick you are trying to do by restarting the slave driver and moving it around on the pins.
Try out this hacked version. I think it should work. I put in all the code for the function calls so that the locking is not bypassed.
Oh, I see. Got it. I'm going to test this right away... Thanks a lot, Kye!
NOTE: You need to mount the file system like regular.
Thanks Kye.
I've tested & the result is the same. I've placed some debugging statements outputting to PST. It still hangs at readLowLevelSector() and I don't know why. I've tried increasing the stack all the way to 1_024 but that didn't help. I'm attaching the uSD controller object file.
PST OUTPUT
I can access both the Master & Client1 drive but it didn't display ""After readLowLevelSector of Master ..." after the readLowLevelSector().
Thanks a lot.
Sorry about that. (re-attaching). Yeah, no problem. You had been a great help already. I'll continue working on this. Thanks a lot.
That's right.
Hmm ... don't get it, I could access Master drive just before the function. I've tried swapping with other the cards but result still the same...
It seems like you want to have 4 uSD cards at the same time. It that is the case then you need to have 4 separately named versions of the driver.
... Yeah, I know, not enough memory for that. Including the same named driver file more then once just allows you to have more than one file open. I.e. a file open per included version of the driver.
---
So, do you even need the file system layer? You could just decapitate the file system part from the block driver.
Also... I think you might have an easier time just using FSRW's block driver. It will allow you to do what you want more easily. I recommend that you use it. You'll get much faster transfer speeds also.
Thanks a lot.
Kyedos is doing great behind the scenes running the touchscreen GUI and all the fun demos like a touchscreen synthesizer.
Is there an error code to tell if a fat.open has failed?
I think at the moment it returns a pointer to a string and the string contains a message saying it worked or didn't work.
Could you get the first 4 letters of that string and use them to determine "success" or "fail"? Or is there a better way?
Many thanks - drac.
Thanks,
I think that having an SD card is an excellent place to store logging data for any project and..
This FAT driver already has all the needed stuff like getting date and time for a timestamp and of course handling the file writing.
A function like
With
- "Severity" being a constant enumeration (Information/Warning/Error/Critical/etc)
- "Message" a user defined text string
This function would append in a user defined (or fixed) file a whole line of text that includes at least the following fields separated with a defined char like space/commas/tabs/etc
- timestamp
- cog number (optional, but would help))
- Severity in clear text
- message
I can do it myself but surely You will do it faster and I think it would benefit everyone. What do you think?
Thanks in advance
Alex
For example it is possible a user may want to redirect log messages to a serial or network link for recording elsewhere. Or just stream them to a raw fash chip. Better to have a logging API at a higher level that may make use of a file system if wanted.
Heater, I agree on a theoretical basis, however given the limited resources on a Propeller platform I still think a little deviation from a pure subsystem encapsulation is worth the price for the benefit.
BTW, have you seen or have a logging API with the functions you described? For SPIN?
Thanks
Alex
I agree that when resources are constrained perhaps some architectural niceties have to go out the window.
However making a logging system as you describe probably does not take much more space than mixing it into the file system where it will actually waste space for most users who don't use that feature.
I think I am doing something wrong there.
returns zero if the file exists
But if I try that with a file that does not exist, it hangs and never prints anything.
Am I not using this function correctly?
Oh and I found the version that has no RTC and since I don't have a clock I've replaced the code with that version which saves some space.
All working very nicely, Thanks!
If openfile fails it aborts. If the abort is not caught by adding that slash to the call then the program aborts totally and looks like a hang.
Um, don't try 100 MHz with MMC cards. This doesn't work. For SD cards it does though. Try a different SD card.