How to use CRCBIT and/or CRCNIB for CRC7 (for MMC)?
Rayman
Posts: 14,665
in Propeller 2
For uSD, you can ignore the CRC, but eMMC is making me use it...
I tried for a second to use the assembly commands CRCNIB and CRCBIT to speed it up.
But, I can't figure it out...
Anybody know how to do this?
Here's my Spin2 version that works:
I tried for a second to use the assembly commands CRCNIB and CRCBIT to speed it up.
But, I can't figure it out...
Anybody know how to do this?
Here's my Spin2 version that works:
PUB crc7(buffer,count):r | crc, c,i, j,n 'calculate crc of series of bytes for MMC crc := 0 repeat j from 1 to count c := byte[buffer++] 'Number of loops is 8 for first bytes, 7 for last byte if j==count n:=7 else n:=8 repeat i from 1 to n crc <<= 1 if c&$80 crc+=1 if crc&$80 crc^=$9 c<<=1 crc:=crc & $7F r := (crc<<1)+1 return r
Comments
http://forums.parallax.com/discussion/171293/crc8
From this page: http://doitwireless.com/2015/05/31/crc-routines/
Your polynomial is $9.
You may have to reverse the byte c before running the rep loop, and the last loop will need to be 7
You should be able to do something like this Sorry, dont have time to test atm.
or using the crcnib
With the traditional way of shifting in bits, there needs to be preliminary shifts to load the data into the crc result. Not so with CRCBIT since the
incoming bit and the outgoing bit are xor'd to see if the poly needs xor'ing into the result.
This website is helpful: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
I see SMBus is "CRC8_MAXIM" there. The actual polynomial is $31, but we need to use the reversed version, $8C, with the CRCBIT routine, as shown by @JonnyMac
Also, that page says both the input and the output are bit reversed. But, this seems to be done automatically by CRCBIT somehow...
Also, I see a lot of people are using a table to do this... Maybe that's the way to go. I'll just use the LUT, once I figure out how to translate CRC8_MAXIM into CRC7 for MMC...
Or, maybe I can just make the table without actually figuring anything out...
Just use the crcbit or crcnib. You'll be glad you did! Sorry I'm busy at work so I can't get it done for you just now but perhaps later.
Just run a single known character thru the crcnib once (just a nibble( and compare the result with your spin code. Retry with the crc initialised to 0 or $FF, try reversing the characters bits, and the reverse of the polynomial ($31 and $8C). There are not a lot of combinations here and you should find one that matches your spin. BTW Are you sure your spin is correct?
I’ll try and find some time to test it with the crcbit crcnib instructions.
Spent quite some time on this this morning.
I cannot get your code to give the correct results. If you want me to spend any more time on it I need a working program that I can compile with serial output that I can test with. Either pnut or fastspin is fine.
This sequence is a know valid one for SD cards
$40 $00 $00 $00 $00 $95
where $95 is the crc value.
From what I've been able to research, the final crc value calculated is $4A which is then shl #1 and add #1 to give $95.
In hindsight I probably should have gone back to study the algorithm again. I haven't done it since the 80's.
I found this c code but I cannot run it to verify if it works and i don;t understand the "for" statement
filename is crc7expl.zip
It seems this kind of thing is ancient history and not so many people still remember how to do it by hand
There is a left shift and a +1 at the very end.
I think that 1 at the end is actually the stop bit, which is why it is not included in the above...
Here is the important part:
You need to verify a spin program that takes $40 $00 $00 $00 $00 and gives $65. I can then convert it to pasm and then use the crcbit/crcnib instructions.
I think you had it
The shift and 1 at end is the stop bit
EDIT: I replaced byte[@crc] with just crc, and masked it to 8 bits at the end.
EDIT2: I also replaced byte[@val] with just val. cspin was trying very hard to maintain 8-bit values.
Like to make it faster with new crcnib instruction ...
The spin code at the top post is not giving the correct result for the initial command 0 which must be $95 but it returns $93
What is happening is that it is getting the wrong input characters
Found a bug in my code - just retrying.
Yes, the crc generated is wrong:(
It also generates the wrong value $1B which should be $87 for the command8
I’ll try tomorrow ...
Late here...
An alternate CRCNIB may speed this up even more. I'm just not 100% sure what the xx values are. Maybe they are just the same as the single bit case and the HW just figures it out for you. This could then be as fast as 14 clocks per byte if the fifo is used.
I'll try crcnib now
or with the outer loop also in PASM: Andy
I think I'm seeing that I got hung up by the code I found and that last 7 bits of zero it does.
Although it works, it is unlike all the other code...
Now, I have code that just works on the first 5 bytes and doesn't have that dummy 6th byte:
Was just about to figure this all out, but maybe Andy beat me to it...
Or, maybe @"Dave Hein" or @rogloh would work this way too...