Project - Tiny File System

@ rpizzo - No problem, I hope you are able to resolve your issue. Is it just the project using the TinyFileSystem that is causing an issue or is it some other project?

If it is the project with the TinyFileSystem, have you tried creating a new project and just adding the items one by one? So start with an empty project, if that deploys then just add the TFS code, if that deploys then add the initialization code for TFS, if that works then add some code to create a file and so on.

@ Rpizzo,open MFDeploy and check you can communicate to the device. Show us what Device Manager shows. We’ve seen people whose code is in so tight a loop that they have to go into bootloader mode and erase the device and reload the firmware so they can actually get deploying again.

@ Brett - yep sure enough MFDeploy shows I can ping the device fine. I am attaching a screen shot of the DeviceCapabilities result, I assume this is what you meant by Device Manager? Just in case I also have the Windows Device Manager showing the USB connection and device are working.

I have only deployed with Visual Studio 2010, running with F5. I never used MfDeploy to deploy this app and never had an issue till now, out of the blue.
Does anything look incorrect in the Device Capabilities?

I can load, deploy, and run another application with no issues, unless something looks fishy with this screenshot I think my only choice is to create a fresh new solution and slowly add things until it breaks; But I have already tried removing things from this project to no avail.

Thank you all for helping me with this issue!

Everything looks sensible. I would create a brand new project, flashing a LED, and deploy that to prove that there’s nothing wrong with your device or environment.

Then, I would suggest you start a new project and copy over your code. The main reason for doing this is old references and an SDK update - you didn’t seem to mention this, but is there any chance you did that recently? The project stores the actual files you add as references with the project, so only removing all references and re-adding them will eliminate the cached version of them, but to make sure you get them all the best way is just to copy your code over into a new project.

BTW, what I meant about Device Manager was the Windows Device Manager itself - to check what devices became visible, for instance the GHI debuggable .net device appearing is GOOD because it means your device has a correct firmware and booting past the bootloader and into the CLR. If you only got a COM port visible it would show that the device only booting into the bootloader and you would need to do the firmware update again.

@ rpizzo - My understanding of your problem is that you do not have a general deployment issue ie. your projects deploy and run fine, it is only one project that when deployed raises the NullReferenceException.

If I have understood correctly, then a good approach to identify what is causing the issue is to follow the process would be to start with an new project and slowly add the pieces of code until you are able to reproduce the problem. I assume that the issue is with your project using TFS, so I would sugges tthe steps I provided earlier as a starting point to eliminate or prove TFS as being the root of the issue.

If you reach a point where you have added everything and the problem does not present it self, then you have two projects that can be compared to see if there are any project level differences that might be responsible for the issue.

Ok, I created a new solution and slowly moved things over so now I can deploy again. What a pain, still no idea what the real problem was I didn’t change any code and still the same projects as I had in the problem solution.

@ taylorza - Anyhow, I can resume debugging now. I write a file, presumably fine, then reading is another story. I am not able to retrieve the file name. The TinyFileSystem.GetFileName() is bombing. I can see that reading the _cluster I am not getting back the proper bytes, in particular the FileNameLengthOffset used to point to a value of “10” which for a file name of “config.xml” is correct. But now the FileNameLengthOffset points to a value of “0”. So I need to debug more and figure out why it is incorrect. I am still learning the code so it is a bit slower going that I would like.

Should the first file ever written be a clusterId of 0 or 1?
Well, I tried making it either and that FileNameLengthOffset still points to a 0. I will keep at it, I just wanted to report that I am back in the saddle again and proceeding to try some file writes and reads.

I will keep you posted as I find stuff. Thanks so much for your help getting me running again!

@ rpizzo - I am glad to hear that you are up and running. It would be interesting to do a file diff on the csproj file and see if there is something suspicious that can point to the issue you faced.

The first file written will have the initial header (Filename etc.) written to cluster 0, if you then write additional data, that first cluster will be “orphaned” and re-written to cluster 1 with the additional data.

What I just described is what happens in the case that you are not using the buffering, I would suggest that you initially test without the buffering by passing a 0 as the buffer size when creating/opening the file. Buffering adds an addition layer of complexity which is harder to predict exactly where and when the data will be flushed to disk.

@ taylorza - I diffed the csproj files and nothing different! However, there was some other test code that I did NOT copy over to the new solution, this code did compile, deploy and run fine before. Maybe something strange with function size or some other weird quirk.

I tried with and without buffering, and still the same end result. To put it simply, it really looks like what we think we are writing to the chip isn’t getting read back. I put a logic analyzer on the chip and it does indeed look like SPI timing but the value read back doesn’t seem right (always <= 0x16).

Here is how I am configuring the SPI. On my Cerberus I tried socket 5 and 6.
For socket 6 I used
var spiCfg = new SPI.Configuration((Cpu.Pin)FEZCerberus.Pin.PA13, false, 0, 0, false, true, 12000, SPI.SPI_module.SPI1);
For socket 5 I used
var spiCfg = new SPI.Configuration((Cpu.Pin)FEZCerberus.Pin.PC15, false, 0, 0, false, true, 12000, SPI.SPI_module.SPI1);
If I call
SPI.SPI_module spim = GT.Socket.GetSocket(5, true, null, null).SPIModule;
with either a 5 or 6 for the first param (socket id), it always returns 0, thus the usage of SPI.SPI_module.SPI1 for either socket 5 or 6

Further, the GET_IDENTIFICATION is returning something but not what the code in MX25l3206BlockDriver says the manufacturer and device id should be.

Can someone check my SPI.Configuration’s and tell me if I am off with these? I suspect this is a likely cause of the trouble.
Hopefully we have good news soon!

@ rpizzo - Can I make a suggestion?

It might be worth trying just some low-level access to the device. The code I have for the device access is based off the sample code from GHI in this post http://www.tinyclr.com/forum/topic?id=8324&page=5#msg83247.

If you can test to see if this code reads/writes data successfully and then compare that with my re-factored version of this code in MX25l3206BlockDriver.cs class MX25l3206. The re-factoring was done blind so it might be that I have introduced an issue there.

I appreciate your assistance and patience.

@ taylorza - I did as you suggested, using the exact low level access code you referenced. I erased the chip, wrote some data, and read the same data back! I cleared the buffer first before the read to make sure I wasn’t looking at any remnants, so assuming the spi functions work (which I know they do), this should have been a valid test.
I also tried both SPI configs I posted earlier and it worked on socket 5 and 6 equally well.

Next step I will see if I can find any differences in the code I just tried from GHI and the code in the MX25l3206BlockDriver.

Thanks for that suggestion I feel like we are a step closer now!

@ rpizzo - Have you had a chance to test the Driver implementation compared to the GHI code?

@ taylorza - I replaced the low level driver implementation with the same from the GHI code. There is still something wrong that the read doesn’t come back with what is supposedly written.

I wasn’t expecting this. I was actually expecting success since the GHI code by itself seems to write and read fine but when I use it with the file system layer on top, the read is always “off” in that the file name for example isn’t where it should be but rather some spurious value is at the offset of the cluster.
I have no choice but to just debug this further, unfortunately I am away on business this week and don’t have my hardware with me but I do have all the code so I can review the code at least.

Wish I had better news :frowning: But I am sure we are closer now!

@ rpizzo - Thank you for your efforts. I have placed an order with Mouser to get a physical device, unfortunately it is on back order with them so I do not know how long it is going to take for me to actually get the device. And clearly my emulation of the device is missing some critical piece of the puzzle.

I appreciate your efforts!

Ok, read this whole thread and looked at the Tiny File System. I am impressed with the file system, but confused by the driver situation. I just got one of the GHI Flash modules and it is using a Spansion FL032PIF 4MB Flash chip (Mountaineer uses Spansion FL064KIF). But the driver in the TinyFS project is for Macronix MX25L3206 which is apparently a completely different flash chip (see spec sheets below). But, in comparing the commands from the spec sheets, they appear to be similar or identical, albeit from different manufacturers. Is there a standard for the Flash SPI commands?

Also, I thought I read somewhere that Gus said that GHI would provide a low level Block access class for the Flash module, but the File System would be up to the community… But I can’t seem to find that code or the post where Gus said that…

Spansion Spec sheet:
http://www.spansion.com/Support/Datasheets/S25FL032P_00.pdf

Macronix Spec sheet:
http://www.macronix.com/QuickPlace/hq/PageLibrary4825740B00298A3B.nsf/h_Index/3F21BAC2E121E17848257639003A3146/$File/MX25L3206E,%203V,%2032Mb,%20v1.4.pdf

Update: Ok, I found the thread where Gus provided the driver here: http://www.tinyclr.com/forum/topic?id=8324&page=3#msg82271

@ Valkyrie-MT - I should add that I tried all my tests with both the GHI module and my own module that I built while waiting for the GHI module to be released, and my board uses the Macronix MX25L3206. Looks like the commands are the same and they are the same device, basically. I get the same results with both boards.

Today is a good day. After a long ordeal, I finally managed to get a Flash module. I eventually ordered it from Mouser. I have updated the code for Tiny File System with the changes required for the file system to work with the real device.

Interestingly the problem was with the SPI WriteRead, it did something that was totally unexpected. The data in the read array is always offset by the index + the length of the write array. So I needed to compensate for this offset of 4 bytes.

So now there is a functioning File System that can be used with the module, I hope someone finds it useful and if there are any issues please let me know, I will gladly work to improve this code.

2 Likes

awesome, well done. great that eventually something arrived - but what a long drawn out saga !

@ Brett - I am telling you, I thought I would never get the module :slight_smile: Mouser did not have any in stock so I had to wait another 4 weeks for them to source the module from GHI. So you can imaging my excitement when the device arrived today, I even left the office early today…

You did a beautiful job on this File System. I have been using it for about 2 weeks. It does seem to have problems when it fills up, so I have decided to use it for half of the flash in a read-only mode. But the implementation with streams is FANTASTIC. I am running a web server from it. I think it doesn’t compact properly when space runs low. So, I ended up creating my own simple storage format for the other half of the chip.