// // Little demo program showing an interleaver. // This is not variable but fixed at 8X8 bits (or 8 bytes in the block). // // So, take an input message that is 8 binary bytes. // Our INMSG buffer will hold the message in the "natural" order. This // block would probably have some FEC in it based on this order. // // Say that our input message is: {0x01, 0x02, 0x03, 0x04, 0xFF, 0xFE, 0xFD, 0xFC} // // Interpret the block of data in terms of a table as follows: // // Column // 0 1 2 3 4 5 6 7 // +---------------+ // 0|0 0 0 0 0 0 0 1| 0x01 // 1|0 0 0 0 0 0 1 0| 0x02 // R 2|0 0 0 0 0 0 1 1| 0x03 // O 3|0 0 0 0 0 1 0 0| 0x04 // W 4|1 1 1 1 1 1 1 1| 0xFF // 5|1 1 1 1 1 1 1 0| 0xFE // 6|1 1 1 1 1 1 0 1| 0xFD // 7|1 1 1 1 1 1 0 0| 0xFC // +---------------+ // // We want to transpose the columns and rows and change the table to: // // Column // 0 1 2 3 4 5 6 7 // +---------------+ // 0|0 0 0 0 1 1 1 1| 0x0F // 1|0 0 0 0 1 1 1 1| 0x0F // R 2|0 0 0 0 1 1 1 1| 0x0F // O 3|0 0 0 0 1 1 1 1| 0x0F // W 4|0 0 0 0 1 1 1 1| 0x0F // 5|0 0 0 1 1 1 1 0| 0x1F // 6|0 1 1 0 1 1 0 0| 0x6C // 7|1 0 1 0 1 0 1 0| 0xAA // +---------------+ // // #include #include #include // Set up some buffers for our test messages. // #define MAX_MSG 8 unsigned char inmsg[MAX_MSG]; // Original message unsigned char ileavedmsg[MAX_MSG]; // Interleaved message unsigned char outmsg[MAX_MSG]; // Descrambled message int interleave8x8 (unsigned char * inbuf, unsigned char * outbuf); int deinterleave8x8 (unsigned char * inbuf, unsigned char * outbuf); int getbit (unsigned char *x, int row, int column); int putbit (unsigned char *x, int row, int column, int value); int msglen = 8; // Test message.. unsigned char test_msg1[] = {0x01, 0x02, 0x03, 0x04, 0xFF, 0xFE, 0xFD, 0xFC}; int main () { int i, bitnum, nerrors; int sbit; unsigned char data; // Copy test message into the first buffer msglen = sizeof(test_msg1); for (i = 0; i < sizeof(test_msg1); i++) inmsg[i] = test_msg1[i]; // Display our starting message in HEX printf ("\n***** Dumping the initial message of (%0d) bytes", msglen); for (i = 0; i < msglen; i++) { if ((i % 16) == 0) printf ("\n"); printf ("%02X ", inmsg[i]); } printf ("\n\n"); // Interleave the message interleave8x8 (inmsg, ileavedmsg); // Dump the Interleaved message printf ("\n***** Dumping the interleaved message"); for (i = 0; i < msglen; i++) { if ((i % 16) == 0) printf ("\n"); printf ("%02X ", ileavedmsg[i]); } printf ("\n\n"); // *** OK. Pretend we've transmitted our bits... Now its time to deinterleave it back. // Descramble the message (use the same algorithm - its a symetric operation!) deinterleave8x8 (ileavedmsg, outmsg); // Dump the Deinterleaved message printf ("\n***** Dumping the deinterleaved message"); for (i = 0; i < msglen; i++) { if ((i % 16) == 0) printf ("\n"); printf ("%02X ", outmsg[i]); } printf ("\n\n"); // I guess we should verify the final deinterleaved message is, in fact, the same as original. nerrors = 0; for (i = 0; i < msglen; i++) { if (inmsg[i] != outmsg[i]) { printf ("\nMismatch!"); nerrors++; } } if (nerrors == 0) { printf ("\nSuccess: received buffer matches original buffer."); } printf ("\nThat's it."); printf ("\n"); } int interleave8x8 (unsigned char * inbuf, unsigned char * outbuf) { int column, row; int b; // Access each bit in the implied order of the data. for (row = 0; row < 8; row++) { for (column = 0; column < 8; column++) { b = getbit (inbuf, row, column); // Get the bit putbit (outbuf, column, row, b); // SWAP row and column!! } } return 0; } int deinterleave8x8 (unsigned char * inbuf, unsigned char * outbuf) { int column, row; int b; // Access each bit in the interleaved order of the data. for (column = 0; column < 8; column++) { for (row = 0; row < 8; row++) { b = getbit (inbuf, row, column); // Get the bit putbit (outbuf, column, row, b); // SWAP row and column!! } } return 0; } // *** Access functions // // GET a bit.. int getbit (unsigned char *x, int row, int column) { return x[row] & (1 << (7-column)); } // PUT a bit.. int putbit (unsigned char *x, int row, int column, int value) { if (value) { // Set x[row] |= (1 << (7-column)); } else { // Clear x[row] &= ~(1 << (7-column)); } return value; }