Generating the 10 bit CRC, for the 16 bit data 'block' (4 needed per frame) for
m.r.b.
Posts: 36
I am building a low power FM stereo TX, with RDS functionality
(for getting an MP3 player to connect to a car stereo, with, in the longer term, the track name displayed on the car stereo display, but for the·initially, for testing·a static PS {program service} name " * IPOD * "!· !!)
I'm quite confused by Cyclic Redundancy Checks...· Something I really should learn more about!!!
Could someone help me out with the (spin) code to return the 10 bit CRC, for·a 16 bit data 'block' used within the Radio Data system.
{4 'blocks' are required to form a 'frame' of 104 bytes, to properly display the PS name}
I know pretty much everything else about the baseband coding structure, and also the modulation scheme, but I am stumped by the CRC part of this.... I know what the polynomial is, but I dont know if its byte reversed or not, and whether to set the default state of the CRC to $0000 or $ffff etc)
Any ideas??
·
(for getting an MP3 player to connect to a car stereo, with, in the longer term, the track name displayed on the car stereo display, but for the·initially, for testing·a static PS {program service} name " * IPOD * "!· !!)
I'm quite confused by Cyclic Redundancy Checks...· Something I really should learn more about!!!
Could someone help me out with the (spin) code to return the 10 bit CRC, for·a 16 bit data 'block' used within the Radio Data system.
{4 'blocks' are required to form a 'frame' of 104 bytes, to properly display the PS name}
I know pretty much everything else about the baseband coding structure, and also the modulation scheme, but I am stumped by the CRC part of this.... I know what the polynomial is, but I dont know if its byte reversed or not, and whether to set the default state of the CRC to $0000 or $ffff etc)
Any ideas??
·
Comments
Look at what I found in the top rank of googling "rds crc": http://www.ee.ucl.ac.uk/~hamed/docs/final report.pdf
In there is a clear description on how to do the CRC on a microcontroller.
1. Load the register with zero bits.
2. Augment the message by appending W zero bits to the end of it.
while (more message bits)
begin
3. Shift the register left by one bit, reading the next bit of the augmented message into register bit position 0.
if (a 1 bit popped out of the register during step 3)
register = register XOR Poly.
End.
I think that's pretty clear, or is it?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/24/2010 3:03:57 PM GMT
I tested this routine against pullmoll's assembly version and got the same result from each test. That said... you'll pay the price in speed. I measured the number of clock ticks like this:
... and found that the Spin version took 313_520 clock ticks (3.9ms), while the assembly version took only 6_032 (75.4us) for the same, 10-byte packet. You may need to take this into consideration, depending on the size of your message packets.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
Initially, the SPIN version will be fast enough (Well, at least until I start using a dynamic PS name, later on ...), because·in reality, you only need·to calculate the CRC once for each of the four 'blocks' that makes up the entire data frame.
.... This is·assuming the message data doesnt change (it wont if I stick to a static PS name for initial testing, for·now..)
However, when I start using dynamic (scrolling PS names) at some later time, I will·possibly either use·the ASM code, or use 'double buffered' data (which I only update when I'm ready), and stick to the slower SPIN crc10 method
Because the packet size per block, is allways a fixed width 16 bit message, I've trimmed out the code for counting through multiple pointer referenced message bytes, giving me this even simpler code, for initial testing with static PS name:-
[noparse][[/noparse]code]
pub crc10(blockdata) | tmpcrc
· tmpcrc~
· 'Radio Data System CRC Polynomial G(x) = x^10 + x^8 + x^7 + x^5 + x^4 + x^3 + 1
· 'Polynomial value =· $05b9
· 'Block data is fixed width, 16 bits, so have dispensed with counting through multiple pointer referenced bytes...
·· repeat 16 '16·bits fixed width packet
···· tmpcrc := (tmpcrc << 1) | ((blockdata & $8000) >> 15)
···· if (tmpcrc & |<10)
······ tmpcrc ^= $05b9
···· blockdata <<= 1
· return tmpcrc & $03FF
[noparse][[/noparse]/code]
regards M.R.B.
B.T.W. Sorry for the confusion, there was a typo in my original post, it should have read:-
{4 'blocks' are required to form a 'frame' of 104 bits, to properly display the PS name}