FSRW & safe_spi.spin
BTX
Posts: 674
Hi all.
I need some help to achieve this here.
What I want is to get out each byte that I read from a SD card file, I'm using FSRW26 with safe_spi, well this is not so simple for me, what I want is to catch those bytes into the own safe_spi code, once at a time (or a long at a time), and send those bytes out of the pchip.
I assume that my first step to do, is to locate inside the safe_spi code, where it is getting the bytes read from the SD.
I suppose that it's happening into the: read_single_block loop. is it right ?
And more, is "readback" the variable who contains a long, with four bytes of data read ?
Could I lose some time after get that variable, to send it out of the pchip, before execute the: djnz ops_left,#:read_loop ?, or this will affect the code logic ?
The idea with this is, to get those bytes out the pchip and catch them with a cpld (this is for my Prop2Cpld board). I presume that this will be more fast and efficient, that cath the bytes from the read buffer, and then send them out, using another cog to drive the data out for the cpld.
I need some help to achieve this here.
What I want is to get out each byte that I read from a SD card file, I'm using FSRW26 with safe_spi, well this is not so simple for me, what I want is to catch those bytes into the own safe_spi code, once at a time (or a long at a time), and send those bytes out of the pchip.
I assume that my first step to do, is to locate inside the safe_spi code, where it is getting the bytes read from the SD.
I suppose that it's happening into the: read_single_block loop. is it right ?
And more, is "readback" the variable who contains a long, with four bytes of data read ?
Could I lose some time after get that variable, to send it out of the pchip, before execute the: djnz ops_left,#:read_loop ?, or this will affect the code logic ?
The idea with this is, to get those bytes out the pchip and catch them with a cpld (this is for my Prop2Cpld board). I presume that this will be more fast and efficient, that cath the bytes from the read buffer, and then send them out, using another cog to drive the data out for the cpld.
Comments
Like this:
I don't know if this is what you want, but I wouldn't mess with the PASM in the safe_spi object if I where you, as it could mess up the timing and give you false bytes. Just my opinion.
Thank you Microcontrolled, but that is not what I want to do, and sorry, maybe I can't explain it very well in English.
I will try to explain again it with an example.
Until now, I'm reading the file in the SD using *pread* function, then I save that data in a big buffer, (all the file content). After that, I'm sending out the big buffer data content with another cog (ASM code) in parallel mode by 16 pins (two bytes of the buffer at a time).
What I thought is, send out the data by the same 16 pins, but in the exact momment that the safe_spi read them from the SD card. So, my big buffer dispears, and I could get a fast throughput of the data out. The main reason is so, speed up my task.
I hope it is clear now.
Where are you lonesock and rokicki ??
In the latest FSRW (2.6), the block driver is reading a block ahead (512 bytes), and storing that in a buffer in the cog. To take maximum advantage of that, simply use pread( @buffer, 512 ), to get 512 bytes into a buffer of your choice. Then send that buffer out over the serial port (you may want to modify your serial engine to send a block of bytes, instead of using .tx to send a char at a time...SPIN becomes the bottleneck in that case). While you are sending your buffer, the block driver cog is busy reading the next sequential block of 512 bytes, so when you request the next block of 512 bytes via pread, the odds are good that the data is already in the cog, and just gets copied into your buffer, and the whole things starts again.
Jonathan
But, didn't you read my above posts ?
I don't want to send any by serial, just in parallel mode type " mov outa,somedata "
I'm doing exactly what you suggest until now, but I need more efficient code and speed up it.
I think to put that "mov" instruction into the same read loop of the SD, into each of the 512 bytes block.
What you say is fine, but when I get again the data from the buffer in asm code, I'm loosing time in the rdlong instruction.
Please read my first post in this thread to know it.
If my questions are not clear, I will try to do them again. Thank you so much again.
Yes, you _could_ put your mov outa,data code directly into the read_single_block routine. You would want to place your code directly after I stop the clock and read in the last bit. However you would have to handle the following:
* the bytes come in big-endian (so the safe_spi reads each byte backwards, then reverses all four bytes in the long at once)
* you would not want your output whenever FSRW is reading the FAT table (which happens whenever you open a file, or everytime you switch to a new cluster)
The pread code in FSRW does some overhead, and then copies the data buffer into an intermediate 512-byte buffer, before passing it back to you. If you want to go a bit faster, you can make sure your files are contiguous on the SD card, use FSRW to open the file, get the block ID (address) of the first chunk, then use the safe_spi block layer directly to read each subsequent block of data directly into your own buffer. This cuts out quite a bit of overhead, and gives a decent speedup (25-50%?)...you just *must* make sure that your files are all stored in sequential blocks.
If you want to go the harder route and modify safe_spi directly, let me know...I can help, but my free time is limited.
Jonathan
Yes, yes, you give me another idea too, it is not a problem for me to read data where files are contiguous on the SD card !!
But I'm sure I will need a more detailed help of how to modified code. Simply some recognition of where are the parts of the code to get out. I will analize it, and then I will ask again.
Do you prefeer, I'll do in this thread, or private ?
About the another method, I should put a flag to advice me when the block read is for FAT, or part of the file read....thought.
PS:
I mean that I need help, because there are somethings that I can't finish to understand, as a "mov 0:0,readback" or a mov to a label ??...like "movd :store_read_long,#speed_buf"
Jonathan are you there ?
I did all modifications in the fsrw, and in the safe_spi code succesufully. although I can't get a fast data transfer, comparing it, with my last working code.
Maybe be it's due my new added code is taking about 54 clk cycles to achieve it's data transfer to the CPLD of the board, all this each four bytes of the long read in the readback variable.
It's working fine but it is not usefull for my purposes so.
What I want to try, is what you suggest before to me, but I can't finish to understand how to do that, just only read contiguous blocks and use another cog to transfer them, but what I need is that the read blocks get faster read that in the original safe_spi code.
What speed do you need? (In terms of raw speed reading with safe_spi, I can usually get about 900,000 bytes per second, with periodic card hiccups included) Can you give me any information on your setup (like which pins are connected to your CPLD, and how you transfer data across, and which pins & cog are driving the SD card)? There are faster versions of the spi code, but you have to be careful which pins & cog you use for the block driver code (and to some extent the routing of the clock and data lines).
If you want, we can continue this via email: same username at gmail.com, or we can keep it on the thread.
Jonathan
Hi Jonathan.
It's ok here for me if you want. Some info could be usefull for anyone too. (I will send to you "hot comments" if needed by email).
OK my MicroSd card is mounted at: pin 0.
Then the pchip is sending the data to the CPLD by P8-P15 in 16 bits wide data bus.
I've reserved P4-P7 to let me clk the data, and for some handshaking wires between the CPLD and the pchip. (I know, I know, better I should used P0-P15 for data bus...sorry, it is late now).
What speed I need ? As fast as possible, 1500KBps or 2000KBps, would be better but could be great for me to achieve about 4000KBps (just a dream...impossible in SPI mode).
As I said before, don't care if I enter in the code with the block address to read from the SD card, then I should read about 1200 blocks, and I could be sending them out to the CPLD with another cog, (as I did until now ), the SD read speed is my bottleneck now for me.
I usually get speeds of ~ 1.8 MB/s with this setup (raw reads, not going through FSRW). I have also tested it at 100 MHz without problems giving a 25% speed increase. You could easily use a 6MHz crystal or similar to get a speed bump, if you haven't already.
Jonathan
Yes, I only need one copy of the block driver running.
I will try with mb_rawb_spi.spin...but I can't understand how I use it avoiding fsrw (raw reads) ??. If use a 6Mhz xtal is safe, I will too.
I've tested your suggest of read raw contiguous data using your example (by using mb_rawb_spi), and I found surprised that it works a bit slowly than before using pread with safe_spi.spin.
I also tried to use mb_rawb_spi.spin, instead safe_spi with my original code, and it wont work.
Any ideas why ?
Jonathan