<TODO>
<TODO>
<TODO>
<TODO>
<TODO>
xperipherals_adat.h ADAT peripheral interface xperipherals_adat_tx_1.xc ADAT output peripheral #1 implementation xperipherals_adat_tx_2.xc ADAT output peripheral #2 implementation xperipherals_adat_rx_1.xc ADAT input peripheral #1 implementation xperipherals_adat_rx_2.xc ADAT input peripheral #2 implementation
#ifndef XPERIPHERALS_ADAT__INCLUDED #define XPERIPHERALS_ADAT__INCLUDED // ADAT Wire Format: // // One ADAT block consists of eight frames (frame 0 ... frame 7). // One ADAT block contains eight 24-bit samples and 4 user bits. // // Each frame contains part of a 24-bit sample, bits set to 1, and user bits (last frame). // The 'ones' in each frame prevent a run of more than four zeros. // Samples are placed in the frame MSB first (bit 0 is MSB, bit 23 is LSB). // The last frame is contain the only occurance of a run of more than four zeros. // The last frame's zeros are used for synchronization. // // The diagram belos shows one complete block where: // ***1 represents a bit that's set to one. // ***0 represents a bit that's set to zero. // The N:MM represents (sample number):(sample bit) // // Frame 0 |***1|0:00|0:01|0:02|0:03|***1|0:04|0:05|0:06|0:07|***1|0:08|0:09|0:10|0:11|***1| // |0:12|0:13|0:14|0:15|***1|0:16|0:17|0:18|0:19|***1|0:20|0:21|0:22|0:23|***1|1:00| // // Frame 1 |1:01|1:02|1:03|***1|1:04|1:05|1:06|1:07|***1|1:08|1:09|1:10|1:11|***1|1:12|1:13| // |1:14|1:15|***1|1:16|1:17|1:18|1:19|***1|1:20|1:21|1:22|1:23|***1|2:00|2:01|2:02| // // Frame 2 |2:03|***1|2:04|2:05|2:06|2:07|***1|2:08|2:09|2:10|2:11|***1|2:12|2:13|2:14|2:15| // |***1|2:16|2:17|2:18|2:19|***1|2:20|2:21|2:22|2:23|***1|3:00|3:01|3:02|3:03|***1| // // Frame 3 |3:04|3:05|3:06|3:07|***1|3:08|3:09|3:10|3:11|***1|3:12|3:13|3:14|3:15|***1|3:16| // |3:17|3:18|3:19|***1|3:20|3:21|3:22|3:23|***1|4:00|4:01|4:02|4:03|***1|4:04|4:05| // // Frame 4 |4:06|4:07|***1|4:08|4:09|4:10|4:11|***1|4:12|4:13|4:14|4:15|***1|4:16|4:17|4:18| // |4:19|***1|4:20|4:21|4:22|4:23|***1|5:00|5:01|5:02|5:03|***1|5:04|5:05|5:06|5:07| // // Frame 5 |***1|5:08|5:09|5:10|5:11|***1|5:12|5:13|5:14|5:15|***1|5:16|5:17|5:18|5:19|***1| // |5:20|5:21|5:22|5:23|***1|6:00|6:01|6:02|6:03|***1|6:04|6:05|6:06|6:07|***1|6:08| // // Frame 6 |6:09|6:10|6:11|***1|6:12|6:13|6:14|6:15|***1|6:16|6:17|6:18|6:19|***1|6:20|6:21| // |6:22|6:23|***1|7:00|7:01|7:02|7:03|***1|7:04|7:05|7:06|7:07|***1|7:08|7:09|7:10| // // Frame 7 |7:11|***1|7:12|7:13|7:14|7:15|***1|7:16|7:17|7:18|7:19|***1|7:20|7:21|7:22|7:23| // |***1|***0|***0|***0|***0|***0|***0|***0|***0|***0|***0|***1|Usr0|Usr1|Usr2|Usr3| // // The bit-stream at the phyiscal level representing an ADAT block is NRZI encoded. #include "xsystem_types.h" // These must be defined in "xconfig.h" for each peripheral bus being used // // XPERIPHERALS_ADAT_TX_n No value // XPERIPHERALS_ADAT_TX_n__TILE_NUMBER Integer, XS1 tile number // XPERIPHERALS_ADAT_TX_n__TXD_PORT XS1 port identifier #define XPERIPHERALS_ADAT_TX__INTERFACE( N ) \ \ void xperipherals_adat_tx_##N##__initialize( xuint bclk_divider ); \ void xperipherals_adat_tx_##N##__configure ( clock bit_clock ); \ void xperipherals_adat_tx_##N##__transfer ( xsint wordA, xsint wordB ); XPERIPHERALS_ADAT_TX__INTERFACE( 1 ) XPERIPHERALS_ADAT_TX__INTERFACE( 2 ) // These must be defined in "xconfig.h" for each peripheral bus being used // // XPERIPHERALS_ADAT_RX_n No value // XPERIPHERALS_ADAT_RX_n__TILE_NUMBER Integer, XS1 tile number // XPERIPHERALS_ADAT_RX_n__RXD_PORT XS1 port identifier #define XPERIPHERALS_ADAT_RX__INTERFACE( N ) \ \ void xperipherals_adat_rx_##N##__init ( xuint bclk_divider ); \ void xperipherals_adat_rx_##N##__config( clock bit_clock ); \ xbool xperipherals_adat_rx_##N##__phase0( xsint& sample_0, xsint& sample_1 ); \ xbool xperipherals_adat_rx_##N##__phase1( xsint& sample_1, xsint& sample_2 ); \ xbool xperipherals_adat_rx_##N##__phase2( xsint& sample_2, xsint& sample_3 ); \ xbool xperipherals_adat_rx_##N##__phase3( xsint& sample_3, xsint& sample_4 ); \ xbool xperipherals_adat_rx_##N##__phase4( xsint& sample_4, xsint& sample_5 ); \ xbool xperipherals_adat_rx_##N##__phase5( xsint& sample_5, xsint& sample_6 ); \ xbool xperipherals_adat_rx_##N##__phase6( xsint& sample_6, xsint& sample_7 ); \ xbool xperipherals_adat_rx_##N##__phase7( xsint& sample_7, xuint& userdata ); XPERIPHERALS_ADAT_RX__INTERFACE( 1 ) XPERIPHERALS_ADAT_RX__INTERFACE( 2 ) #endif
#include <xs1.h> #include <platform.h> #include <xclib.h> #include <print.h> #include <stdio.h> #include "xperipherals_adat.h" // 256-Bit ADAT Packet // // The packet structure below shows [Channel Number]:[Sample Bit Pos] for audio samples. // The 256-bit sequence is NRZI encoded when transmitting and NRZI decoded when receiving. // Samples are serialized MSB first (:00 represents MSB and :23 represents LSB) // // Note: Bit stuffing with 'ones' every fifth bit and NRZI encoding prevents long runs // of zeros. The zero's at the end of the frame are used for frame synchronization. // // 0 |one |0:00|0:01|0:02|0:03|one |0:04|0:05|0:06|0:07|one |0:08|0:09|0:10|0:11|one | // |0:12|0:13|0:14|0:15|one |0:16|0:17|0:18|0:19|one |0:20|0:21|0:22|0:23|one |1:00| // 1 |1:01|1:02|1:03|one |1:04|1:05|1:06|1:07|one |1:08|1:09|1:10|1:11|one |1:12|1:13| // |1:14|1:15|one |1:16|1:17|1:18|1:19|one |1:20|1:21|1:22|1:23|one |2:00|2:01|2:02| // 2 |2:03|one |2:04|2:05|2:06|2:07|one |2:08|2:09|2:10|2:11|one |2:12|2:13|2:14|2:15| // |one |2:16|2:17|2:18|2:19|one |2:20|2:21|2:22|2:23|one |3:00|3:01|3:02|3:03|one | // 3 |3:04|3:05|3:06|3:07|one |3:08|3:09|3:10|3:11|one |3:12|3:13|3:14|3:15|one |3:16| // |3:17|3:18|3:19|one |3:20|3:21|3:22|3:23|one |4:00|4:01|4:02|4:03|one |4:04|4:05| // 4 |4:06|4:07|one |4:08|4:09|4:10|4:11|one |4:12|4:13|4:14|4:15|one |4:16|4:17|4:18| // |4:19|one |4:20|4:21|4:22|4:23|one |5:00|5:01|5:02|5:03|one |5:04|5:05|5:06|5:07| // 5 |one |5:08|5:09|5:10|5:11|one |5:12|5:13|5:14|5:15|one |5:16|5:17|5:18|5:19|one | // |5:20|5:21|5:22|5:23|one |6:00|6:01|6:02|6:03|one |6:04|6:05|6:06|6:07|one |6:08| // 6 |6:09|6:10|6:11|one |6:12|6:13|6:14|6:15|one |6:16|6:17|6:18|6:19|one |6:20|6:21| // |6:22|6:23|one |7:00|7:01|7:02|7:03|one |7:04|7:05|7:06|7:07|one |7:08|7:09|7:10| // 7 |7:11|one |7:12|7:13|7:14|7:15|one |7:16|7:17|7:18|7:19|one |7:20|7:21|7:22|7:23| // |one |zero|zero|zero|zero|zero|zero|zero|zero|zero|zero|one |usr0|usr1|usr2|usr3| #ifdef XSTREAMM_IO__ADAT_TX_1 on tile[XPERIPHERALS_ADAT_TX_1__TILE_NUMBER] : out buffered port:32 _xperipherals_adat_tx_1__port_txd = XPERIPHERALS_ADAT_TX_1__TXD_PORT; static xuint _bclk_divider; static xuint _encode_lut1[256]; static xbyte _encode_lut2[256]; static xuint _enc_word; //static xuint _tx_carry; //static xuint _tx_stage; static xuint _slot_number; static xuint _step_number = 0; void xperipherals_adat_tx_1__initialize( xuint bclk_divider ) { _bclk_divider = bclk_divider; _enc_word = 0; //_tx_carry = 0; //_tx_stage = 0; _slot_number = 0; // bit clock frequency = 1 * ADAT bit rate = 12.288 / 11.2896 MHz for( int j = 0; j < 256; ++j ) { xuint carry = 0; xuint data = 0b1000010000 | ((j & 0xF0) << 1) | (j & 0x0F); _encode_lut1[j] = 0; for( int i = 0; i < 10; ++i, data <<= 1 ) { if( data & 0b1000000000 ) carry = !carry; _encode_lut1[j] = (_encode_lut1[j] << 1) | carry; } } // bit clock frequency = 2 * ADAT bit rate = 24.576 / 22.5792 MHz if( bclk_divider == 1 ) { for( int j = 0; j < 256; ++j ) { xuint x = _encode_lut1[j]; _encode_lut1[j] = 0; for( int i = 9; i >= 0; --i ) { if( x & (1 << i) ) _encode_lut1[j] |= 3 << (2*i); } } } // bit clock frequency = 4 * ADAT bit rate = 49.152 / 45.1584 MHz if( bclk_divider == 2 ) { for( int j = 0; j < 256; ++j ) { xuint x = _encode_lut1[j]; _encode_lut1[j] = _encode_lut2[j] = 0; for( int i = 9; i >= 8; --i ) { if( x & (1 << i) ) _encode_lut2[j] |= 15 << (4*(i-8)); } for( int i = 7; i >= 0; --i ) { if( x & (1 << i) ) _encode_lut1[j] |= 15 << (4*i); } //printf( "%05x %02x%08x\n", x, _encode_lut2[j], _encode_lut1[j] ); } } } void xperipherals_adat_tx_1__configure( clock bit_clock ) { configure_out_port_no_ready( _xperipherals_adat_tx_1__port_txd, bit_clock, 0 ); clearbuf( _xperipherals_adat_tx_1__port_txd ); _enc_word = 0; //_tx_carry = 0; //_tx_stage = 0; _slot_number = 0; } #if XPERIPHERALS_ADAT_TX_1__BCLK_SPEED == 1 static void _encode_data( xuint sample, xuint byte_num ) { int shift = 8 * (3 - byte_num); if( _enc_word & 1 ) _enc_word = ~_encode_lut1[255 & (sample >> shift)] & 0x3FF; else _enc_word = _encode_lut1[255 & (sample >> shift)] & 0x3FF; } #elif XPERIPHERALS_ADAT_TX_1__BCLK_SPEED == 2 static void _encode_data( xuint sample, xuint byte_num ) { int shift = 8 * (3 - byte_num); if( _enc_word & 1 ) _enc_word = ~_encode_lut1[255 & (sample >> shift)] & 0xFFFFF; else _enc_word = _encode_lut1[255 & (sample >> shift)] & 0xFFFFF; } #elif XPERIPHERALS_ADAT_TX_1__BCLK_SPEED == 3 static void _encode_data( xuint sample, xuint byte_num ) { } #endif // 0.42 usec + 0.34 usec * 7 = 2.8 usec // 2.7 usec #if XPERIPHERALS_ADAT_TX_1__BCLK_SPEED == 1 void xperipherals_adat_tx_1__transfer( xsint wordA, xsint wordB ) { xuint data; switch( _slot_number ) { // | 1 |0:0|0:0|0:0|0:0| 1 |0:0|0:0|0:0|0:0| 1 |0:1|0:1|0:1|0:1| 1 | // |0:1|0:1|0:1|0:1| 1 |0:2|0:2|0:2|0:2| 1 |0:2|0:2|0:2|0:2| 1 |1:0| case 0: _encode_data( wordA, 0 ); data = _enc_word << 22; _encode_data( wordA, 1 ); data |= _enc_word << 12; _encode_data( wordA, 2 ); data |= _enc_word << 2; _encode_data( wordB, 0 ); data |= _enc_word >> 8; break; // |1:0|1:0|1:0| 1 |1:0|1:0|1:0|1:0| 1 |1:1|1:1|1:1|1:1| 1 |1:1|1:1| // |1:1|1:1| 1 |1:2|1:2|1:2|1:2| 1 |1:2|1:2|1:2|1:2| 1 |2:0|2:0|2:0| case 1: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 1 ); data |= _enc_word << 14; _encode_data( wordA, 2 ); data |= _enc_word << 4; _encode_data( wordB, 0 ); data |= _enc_word >> 6; break; // |2:0| 1 |2:0|2:0|2:0|2:0| 1 |2:1|2:1|2:1|2:1| 1 |2:1|2:1|2:1|2:1| // | 1 |2:2|2:2|2:2|2:2| 1 |2:2|2:2|2:2|2:2| 1 |3:0|3:0|3:0|3:0| 1 | case 2: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 1 ); data |= _enc_word << 16; _encode_data( wordA, 2 ); data |= _enc_word << 6; _encode_data( wordB, 0 ); data |= _enc_word >> 4; break; // |3:0|3:0|3:0|3:0| 1 |3:1|3:1|3:1|3:1| 1 |3:1|3:1|3:1|3:1| 1 |3:2| // |3:2|3:2|3:2| 1 |3:2|3:2|3:2|3:2| 1 |4:0|4:0|4:0|4:0| 1 |4:0|4:0| case 3: /* Word from prev step */ data = _enc_word << 28; _encode_data( wordA, 1 ); data |= _enc_word << 18; _encode_data( wordA, 2 ); data |= _enc_word << 8; _encode_data( wordB, 0 ); data |= _enc_word >> 2; break; // |4:0|4:0| 1 |4:1|4:1|4:1|4:1| 1 |4:1|4:1|4:1|4:1| 1 |4:2|4:2|4:2| // |4:2| 1 |4:2|4:2|4:2|4:2| 1 |5:0|5:0|5:0|5:0| 1 |5:0|5:0|5:0|5:0| case 4: /* Word from prev step */ data = _enc_word << 30; _encode_data( wordA, 1 ); data |= _enc_word << 20; _encode_data( wordA, 2 ); data |= _enc_word << 10; _encode_data( wordB, 0 ); data |= _enc_word >> 0; break; // | 1 |5:1|5:1|5:1|5:1| 1 |5:1|5:1|5:1|5:1| 1 |5:2|5:2|5:2|5:2| 1 | // |5:2|5:2|5:2|5:2| 1 |6:0|6:0|6:0|6:0| 1 |6:0|6:0|6:0|6:0| 1 |6:1| case 5: _encode_data( wordA, 1 ); data = _enc_word << 22; _encode_data( wordA, 2 ); data |= _enc_word << 12; _encode_data( wordB, 0 ); data |= _enc_word << 2; _encode_data( wordB, 1 ); data |= _enc_word >> 8; break; // |6:1|6:1|6:1| 1 |6:1|6:1|6:1|6:1| 1 |6:2|6:2|6:2|6:2| 1 |6:2|6:2| // |6:2|6:2| 1 |7:0|7:0|7:0|7:0| 1 |7:0|7:0|7:0|7:0| 1 |7:1|7:1|7:1| case 6: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 2 ); data |= _enc_word << 14; _encode_data( wordB, 0 ); data |= _enc_word << 4; _encode_data( wordB, 1 ); data |= _enc_word >> 6; break; // |7:1| 1 |7:1|7:1|7:1|7:1| 1 |7:2|7:2|7:2|7:2| 1 |7:2|7:2|7:2|7:2| // | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |ub0|ub1|ub2|ub3| case 7: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 2 ); data |= _enc_word << 16; // TODO - encode user data rather than hard-coding zeros //if( _enc_word & 1 ) _tx_carry = data |= 0b0000000000011111; if( _enc_word & 1 ) data |= 0b0000000000011111; else _enc_word = data |= 0b1111111111100000; _enc_word = data; break; } _xperipherals_adat_tx_1__port_txd <: bitrev( data ); if( ++_slot_number == 8 ) _slot_number = 0; } #elif XPERIPHERALS_ADAT_TX_1__BCLK_SPEED == 2 void xperipherals_adat_tx_1__transfer_slot( xsint wordA, xsint wordB ) { switch( _slot_number ) { case 0: switch( _step_number ) { // | 1 | 1 |0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0| 1 | 1 |0:0|0:0|0:0|0:0| // |0:0|0:0|0:0|0:0| 1 | 1 |0:1|0:1|0:1|0:1|0:1|0:1|0:1|0:1| 1 | 1 | case 0: _encode_data( wordA, 0 ); data = _enc_word << 12; _encode_data( wordA, 1 ); data |= _enc_word >> 8; break; // |0:1|0:1|0:1|0:1|0:1|0:1|0:1|0:1| 1 | 1 |0:2|0:2|0:2|0:2|0:2|0:2| // |0:2|0:2| 1 | 1 |0:2|0:2|0:2|0:2|0:2|0:2|0:2|0:2| 1 | 1 |1:0|1:0| case 1: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 2 ); data |= _enc_word << 4; _encode_data( wordB, 0 ); data |= _enc_word >> 8; break; } break; case 1: switch( _step_number ) { // |1:0|1:0|1:0|1:0|1:0|1:0| 1 | 1 |1:0|1:0|1:0|1:0|1:0|1:0|1:0|1:0| // | 1 | 1 |1:1|1:1|1:1|1:1|1:1|1:1|1:1|1:1| 1 | 1 |1:1|1:1|1:1|1:1| case 1: /* Word from prev step */ data = _enc_word << 16; _encode_data( wordA, 1 ); data |= _enc_word >> 4; break; // |1:1|1:1|1:1|1:1| 1 | 1 |1:2|1:2|1:2|1:2|1:2|1:2|1:2|1:2| 1 | 1 | // |1:2|1:2|1:2|1:2|1:2|1:2|1:2|1:2| 1 | 1 |2:0|2:0|2:0|2:0|2:0|2:0| case 1: _encode_data( wordA, 1 ); data |= _enc_word << 28; _encode_data( wordB, 24 ); data |= _enc_word >> 6; break; } break; // |2:0| 1 |2:0|2:0|2:0|2:0| 1 |2:1|2:1|2:1|2:1| 1 |2:1|2:1|2:1|2:1| // | 1 |2:2|2:2|2:2|2:2| 1 |2:2|2:2|2:2|2:2| 1 |3:0|3:0|3:0|3:0| 1 | case 2: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 16 ); data |= _enc_word << 16; _encode_data( wordA, 8 ); data |= _enc_word << 6; _encode_data( wordB, 24 ); data |= _enc_word >> 4; break; // |3:0|3:0|3:0|3:0| 1 |3:1|3:1|3:1|3:1| 1 |3:1|3:1|3:1|3:1| 1 |3:2| // |3:2|3:2|3:2| 1 |3:2|3:2|3:2|3:2| 1 |4:0|4:0|4:0|4:0| 1 |4:0|4:0| case 3: /* Word from prev step */ data = _enc_word << 28; _encode_data( wordA, 16 ); data |= _enc_word << 18; _encode_data( wordA, 8 ); data |= _enc_word << 8; _encode_data( wordB, 24 ); data |= _enc_word >> 2; break; // |4:0|4:0| 1 |4:1|4:1|4:1|4:1| 1 |4:1|4:1|4:1|4:1| 1 |4:2|4:2|4:2| // |4:2| 1 |4:2|4:2|4:2|4:2| 1 |5:0|5:0|5:0|5:0| 1 |5:0|5:0|5:0|5:0| case 4: /* Word from prev step */ data = _enc_word << 30; _encode_data( wordA, 16 ); data |= _enc_word << 20; _encode_data( wordA, 8 ); data |= _enc_word << 10; _encode_data( wordB, 24 ); data |= _enc_word >> 0; break; // | 1 |5:1|5:1|5:1|5:1| 1 |5:1|5:1|5:1|5:1| 1 |5:2|5:2|5:2|5:2| 1 | // |5:2|5:2|5:2|5:2| 1 |6:0|6:0|6:0|6:0| 1 |6:0|6:0|6:0|6:0| 1 |6:1| case 5: _encode_data( wordA, 16 ); data = _enc_word << 22; _encode_data( wordA, 8 ); data |= _enc_word << 12; _encode_data( wordB, 24 ); data |= _enc_word << 2; _encode_data( wordB, 16 ); data |= _enc_word >> 8; break; // |6:1|6:1|6:1| 1 |6:1|6:1|6:1|6:1| 1 |6:2|6:2|6:2|6:2| 1 |6:2|6:2| // |6:2|6:2| 1 |7:0|7:0|7:0|7:0| 1 |7:0|7:0|7:0|7:0| 1 |7:1|7:1|7:1| case 6: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 8 ); data |= _enc_word << 14; _encode_data( wordB, 24 ); data |= _enc_word << 4; _encode_data( wordB, 16 ); data |= _enc_word >> 6; break; // |7:1| 1 |7:1|7:1|7:1|7:1| 1 |7:2|7:2|7:2|7:2| 1 |7:2|7:2|7:2|7:2| // | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |ub0|ub1|ub2|ub3| case 7: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 8 ); data |= _enc_word << 16; // TODO - encode user data rather than hard-coding zeros //if( _enc_word & 1 ) _tx_carry = data |= 0b0000000000011111; if( _enc_word & 1 ) data |= 0b0000000000011111; else _enc_word = data |= 0b1111111111100000; _enc_word = data; break; } _xperipherals_adat_tx_1__port_txd <: bitrev( data ); } #elif XPERIPHERALS_ADAT_TX_1__BCLK_SPEED == 4 #endif #endif
#include <xs1.h> #include <platform.h> #include <xclib.h> #include <print.h> #include <stdio.h> #include "xperipherals_adat.h" // 256-Bit ADAT Packet // // The packet structure below shows [Channel Number]:[Sample Bit Pos] for audio samples. // The 256-bit sequence is NRZI encoded when transmitting and NRZI decoded when receiving. // Samples are serialized MSB first (:00 represents MSB and :23 represents LSB) // // Note: Bit stuffing with 'ones' every fifth bit and NRZI encoding prevents long runs // of zeros. The zero's at the end of the frame are used for frame synchronization. // // 0 |one |0:00|0:01|0:02|0:03|one |0:04|0:05|0:06|0:07|one |0:08|0:09|0:10|0:11|one | // |0:12|0:13|0:14|0:15|one |0:16|0:17|0:18|0:19|one |0:20|0:21|0:22|0:23|one |1:00| // 1 |1:01|1:02|1:03|one |1:04|1:05|1:06|1:07|one |1:08|1:09|1:10|1:11|one |1:12|1:13| // |1:14|1:15|one |1:16|1:17|1:18|1:19|one |1:20|1:21|1:22|1:23|one |2:00|2:01|2:02| // 2 |2:03|one |2:04|2:05|2:06|2:07|one |2:08|2:09|2:10|2:11|one |2:12|2:13|2:14|2:15| // |one |2:16|2:17|2:18|2:19|one |2:20|2:21|2:22|2:23|one |3:00|3:01|3:02|3:03|one | // 3 |3:04|3:05|3:06|3:07|one |3:08|3:09|3:10|3:11|one |3:12|3:13|3:14|3:15|one |3:16| // |3:17|3:18|3:19|one |3:20|3:21|3:22|3:23|one |4:00|4:01|4:02|4:03|one |4:04|4:05| // 4 |4:06|4:07|one |4:08|4:09|4:10|4:11|one |4:12|4:13|4:14|4:15|one |4:16|4:17|4:18| // |4:19|one |4:20|4:21|4:22|4:23|one |5:00|5:01|5:02|5:03|one |5:04|5:05|5:06|5:07| // 5 |one |5:08|5:09|5:10|5:11|one |5:12|5:13|5:14|5:15|one |5:16|5:17|5:18|5:19|one | // |5:20|5:21|5:22|5:23|one |6:00|6:01|6:02|6:03|one |6:04|6:05|6:06|6:07|one |6:08| // 6 |6:09|6:10|6:11|one |6:12|6:13|6:14|6:15|one |6:16|6:17|6:18|6:19|one |6:20|6:21| // |6:22|6:23|one |7:00|7:01|7:02|7:03|one |7:04|7:05|7:06|7:07|one |7:08|7:09|7:10| // 7 |7:11|one |7:12|7:13|7:14|7:15|one |7:16|7:17|7:18|7:19|one |7:20|7:21|7:22|7:23| // |one |zero|zero|zero|zero|zero|zero|zero|zero|zero|zero|one |usr0|usr1|usr2|usr3| #ifdef XSTREAMM_IO__ADAT_TX_2 on tile[XPERIPHERALS_ADAT_TX_2__TILE_NUMBER] : out buffered port:32 _xperipherals_adat_tx_2__port_txd = XPERIPHERALS_ADAT_TX_2__TXD_PORT; static xuint _bclk_divider; static xuint _encode_lut1[256]; static xbyte _encode_lut2[256]; static xuint _enc_word; //static xuint _tx_carry; //static xuint _tx_stage; static xuint _slot_number; static xuint _step_number = 0; void xperipherals_adat_tx_2__initialize( xuint bclk_divider ) { _bclk_divider = bclk_divider; _enc_word = 0; //_tx_carry = 0; //_tx_stage = 0; _slot_number = 0; // bit clock frequency = 1 * ADAT bit rate = 12.288 / 11.2896 MHz for( int j = 0; j < 256; ++j ) { xuint carry = 0; xuint data = 0b1000010000 | ((j & 0xF0) << 1) | (j & 0x0F); _encode_lut1[j] = 0; for( int i = 0; i < 10; ++i, data <<= 1 ) { if( data & 0b1000000000 ) carry = !carry; _encode_lut1[j] = (_encode_lut1[j] << 1) | carry; } } // bit clock frequency = 2 * ADAT bit rate = 24.576 / 22.5792 MHz if( bclk_divider == 1 ) { for( int j = 0; j < 256; ++j ) { xuint x = _encode_lut1[j]; _encode_lut1[j] = 0; for( int i = 9; i >= 0; --i ) { if( x & (1 << i) ) _encode_lut1[j] |= 3 << (2*i); } } } // bit clock frequency = 4 * ADAT bit rate = 49.152 / 45.1584 MHz if( bclk_divider == 2 ) { for( int j = 0; j < 256; ++j ) { xuint x = _encode_lut1[j]; _encode_lut1[j] = _encode_lut2[j] = 0; for( int i = 9; i >= 8; --i ) { if( x & (1 << i) ) _encode_lut2[j] |= 15 << (4*(i-8)); } for( int i = 7; i >= 0; --i ) { if( x & (1 << i) ) _encode_lut1[j] |= 15 << (4*i); } //printf( "%05x %02x%08x\n", x, _encode_lut2[j], _encode_lut1[j] ); } } } void xperipherals_adat_tx_2__configure( clock bit_clock ) { configure_out_port_no_ready( _xperipherals_adat_tx_2__port_txd, bit_clock, 0 ); clearbuf( _xperipherals_adat_tx_2__port_txd ); _enc_word = 0; //_tx_carry = 0; //_tx_stage = 0; _slot_number = 0; } #if XPERIPHERALS_ADAT_TX_2__BCLK_SPEED == 1 static void _encode_data( xuint sample, xuint byte_num ) { int shift = 8 * (3 - byte_num); if( _enc_word & 1 ) _enc_word = ~_encode_lut1[255 & (sample >> shift)] & 0x3FF; else _enc_word = _encode_lut1[255 & (sample >> shift)] & 0x3FF; } #elif XPERIPHERALS_ADAT_TX_2__BCLK_SPEED == 2 static void _encode_data( xuint sample, xuint byte_num ) { int shift = 8 * (3 - byte_num); if( _enc_word & 1 ) _enc_word = ~_encode_lut1[255 & (sample >> shift)] & 0xFFFFF; else _enc_word = _encode_lut1[255 & (sample >> shift)] & 0xFFFFF; } #elif XPERIPHERALS_ADAT_TX_2__BCLK_SPEED == 3 static void _encode_data( xuint sample, xuint byte_num ) { } #endif // 0.42 usec + 0.34 usec * 7 = 2.8 usec // 2.7 usec #if XPERIPHERALS_ADAT_TX_2__BCLK_SPEED == 1 void xperipherals_adat_tx_2__transfer( xsint wordA, xsint wordB ) { xuint data; switch( _slot_number ) { // | 1 |0:0|0:0|0:0|0:0| 1 |0:0|0:0|0:0|0:0| 1 |0:1|0:1|0:1|0:1| 1 | // |0:1|0:1|0:1|0:1| 1 |0:2|0:2|0:2|0:2| 1 |0:2|0:2|0:2|0:2| 1 |1:0| case 0: _encode_data( wordA, 0 ); data = _enc_word << 22; _encode_data( wordA, 1 ); data |= _enc_word << 12; _encode_data( wordA, 2 ); data |= _enc_word << 2; _encode_data( wordB, 0 ); data |= _enc_word >> 8; break; // |1:0|1:0|1:0| 1 |1:0|1:0|1:0|1:0| 1 |1:1|1:1|1:1|1:1| 1 |1:1|1:1| // |1:1|1:1| 1 |1:2|1:2|1:2|1:2| 1 |1:2|1:2|1:2|1:2| 1 |2:0|2:0|2:0| case 1: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 1 ); data |= _enc_word << 14; _encode_data( wordA, 2 ); data |= _enc_word << 4; _encode_data( wordB, 0 ); data |= _enc_word >> 6; break; // |2:0| 1 |2:0|2:0|2:0|2:0| 1 |2:1|2:1|2:1|2:1| 1 |2:1|2:1|2:1|2:1| // | 1 |2:2|2:2|2:2|2:2| 1 |2:2|2:2|2:2|2:2| 1 |3:0|3:0|3:0|3:0| 1 | case 2: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 1 ); data |= _enc_word << 16; _encode_data( wordA, 2 ); data |= _enc_word << 6; _encode_data( wordB, 0 ); data |= _enc_word >> 4; break; // |3:0|3:0|3:0|3:0| 1 |3:1|3:1|3:1|3:1| 1 |3:1|3:1|3:1|3:1| 1 |3:2| // |3:2|3:2|3:2| 1 |3:2|3:2|3:2|3:2| 1 |4:0|4:0|4:0|4:0| 1 |4:0|4:0| case 3: /* Word from prev step */ data = _enc_word << 28; _encode_data( wordA, 1 ); data |= _enc_word << 18; _encode_data( wordA, 2 ); data |= _enc_word << 8; _encode_data( wordB, 0 ); data |= _enc_word >> 2; break; // |4:0|4:0| 1 |4:1|4:1|4:1|4:1| 1 |4:1|4:1|4:1|4:1| 1 |4:2|4:2|4:2| // |4:2| 1 |4:2|4:2|4:2|4:2| 1 |5:0|5:0|5:0|5:0| 1 |5:0|5:0|5:0|5:0| case 4: /* Word from prev step */ data = _enc_word << 30; _encode_data( wordA, 1 ); data |= _enc_word << 20; _encode_data( wordA, 2 ); data |= _enc_word << 10; _encode_data( wordB, 0 ); data |= _enc_word >> 0; break; // | 1 |5:1|5:1|5:1|5:1| 1 |5:1|5:1|5:1|5:1| 1 |5:2|5:2|5:2|5:2| 1 | // |5:2|5:2|5:2|5:2| 1 |6:0|6:0|6:0|6:0| 1 |6:0|6:0|6:0|6:0| 1 |6:1| case 5: _encode_data( wordA, 1 ); data = _enc_word << 22; _encode_data( wordA, 2 ); data |= _enc_word << 12; _encode_data( wordB, 0 ); data |= _enc_word << 2; _encode_data( wordB, 1 ); data |= _enc_word >> 8; break; // |6:1|6:1|6:1| 1 |6:1|6:1|6:1|6:1| 1 |6:2|6:2|6:2|6:2| 1 |6:2|6:2| // |6:2|6:2| 1 |7:0|7:0|7:0|7:0| 1 |7:0|7:0|7:0|7:0| 1 |7:1|7:1|7:1| case 6: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 2 ); data |= _enc_word << 14; _encode_data( wordB, 0 ); data |= _enc_word << 4; _encode_data( wordB, 1 ); data |= _enc_word >> 6; break; // |7:1| 1 |7:1|7:1|7:1|7:1| 1 |7:2|7:2|7:2|7:2| 1 |7:2|7:2|7:2|7:2| // | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |ub0|ub1|ub2|ub3| case 7: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 2 ); data |= _enc_word << 16; // TODO - encode user data rather than hard-coding zeros //if( _enc_word & 1 ) _tx_carry = data |= 0b0000000000011111; if( _enc_word & 1 ) data |= 0b0000000000011111; else _enc_word = data |= 0b1111111111100000; _enc_word = data; break; } _xperipherals_adat_tx_2__port_txd <: bitrev( data ); if( ++_slot_number == 8 ) _slot_number = 0; } #elif XPERIPHERALS_ADAT_TX_2__BCLK_SPEED == 2 void xperipherals_adat_tx_2__transfer_slot( xsint wordA, xsint wordB ) { switch( _slot_number ) { case 0: switch( _step_number ) { // | 1 | 1 |0:0|0:0|0:0|0:0|0:0|0:0|0:0|0:0| 1 | 1 |0:0|0:0|0:0|0:0| // |0:0|0:0|0:0|0:0| 1 | 1 |0:1|0:1|0:1|0:1|0:1|0:1|0:1|0:1| 1 | 1 | case 0: _encode_data( wordA, 0 ); data = _enc_word << 12; _encode_data( wordA, 1 ); data |= _enc_word >> 8; break; // |0:1|0:1|0:1|0:1|0:1|0:1|0:1|0:1| 1 | 1 |0:2|0:2|0:2|0:2|0:2|0:2| // |0:2|0:2| 1 | 1 |0:2|0:2|0:2|0:2|0:2|0:2|0:2|0:2| 1 | 1 |1:0|1:0| case 1: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 2 ); data |= _enc_word << 4; _encode_data( wordB, 0 ); data |= _enc_word >> 8; break; } break; case 1: switch( _step_number ) { // |1:0|1:0|1:0|1:0|1:0|1:0| 1 | 1 |1:0|1:0|1:0|1:0|1:0|1:0|1:0|1:0| // | 1 | 1 |1:1|1:1|1:1|1:1|1:1|1:1|1:1|1:1| 1 | 1 |1:1|1:1|1:1|1:1| case 1: /* Word from prev step */ data = _enc_word << 16; _encode_data( wordA, 1 ); data |= _enc_word >> 4; break; // |1:1|1:1|1:1|1:1| 1 | 1 |1:2|1:2|1:2|1:2|1:2|1:2|1:2|1:2| 1 | 1 | // |1:2|1:2|1:2|1:2|1:2|1:2|1:2|1:2| 1 | 1 |2:0|2:0|2:0|2:0|2:0|2:0| case 1: _encode_data( wordA, 1 ); data |= _enc_word << 28; _encode_data( wordB, 24 ); data |= _enc_word >> 6; break; } break; // |2:0| 1 |2:0|2:0|2:0|2:0| 1 |2:1|2:1|2:1|2:1| 1 |2:1|2:1|2:1|2:1| // | 1 |2:2|2:2|2:2|2:2| 1 |2:2|2:2|2:2|2:2| 1 |3:0|3:0|3:0|3:0| 1 | case 2: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 16 ); data |= _enc_word << 16; _encode_data( wordA, 8 ); data |= _enc_word << 6; _encode_data( wordB, 24 ); data |= _enc_word >> 4; break; // |3:0|3:0|3:0|3:0| 1 |3:1|3:1|3:1|3:1| 1 |3:1|3:1|3:1|3:1| 1 |3:2| // |3:2|3:2|3:2| 1 |3:2|3:2|3:2|3:2| 1 |4:0|4:0|4:0|4:0| 1 |4:0|4:0| case 3: /* Word from prev step */ data = _enc_word << 28; _encode_data( wordA, 16 ); data |= _enc_word << 18; _encode_data( wordA, 8 ); data |= _enc_word << 8; _encode_data( wordB, 24 ); data |= _enc_word >> 2; break; // |4:0|4:0| 1 |4:1|4:1|4:1|4:1| 1 |4:1|4:1|4:1|4:1| 1 |4:2|4:2|4:2| // |4:2| 1 |4:2|4:2|4:2|4:2| 1 |5:0|5:0|5:0|5:0| 1 |5:0|5:0|5:0|5:0| case 4: /* Word from prev step */ data = _enc_word << 30; _encode_data( wordA, 16 ); data |= _enc_word << 20; _encode_data( wordA, 8 ); data |= _enc_word << 10; _encode_data( wordB, 24 ); data |= _enc_word >> 0; break; // | 1 |5:1|5:1|5:1|5:1| 1 |5:1|5:1|5:1|5:1| 1 |5:2|5:2|5:2|5:2| 1 | // |5:2|5:2|5:2|5:2| 1 |6:0|6:0|6:0|6:0| 1 |6:0|6:0|6:0|6:0| 1 |6:1| case 5: _encode_data( wordA, 16 ); data = _enc_word << 22; _encode_data( wordA, 8 ); data |= _enc_word << 12; _encode_data( wordB, 24 ); data |= _enc_word << 2; _encode_data( wordB, 16 ); data |= _enc_word >> 8; break; // |6:1|6:1|6:1| 1 |6:1|6:1|6:1|6:1| 1 |6:2|6:2|6:2|6:2| 1 |6:2|6:2| // |6:2|6:2| 1 |7:0|7:0|7:0|7:0| 1 |7:0|7:0|7:0|7:0| 1 |7:1|7:1|7:1| case 6: /* Word from prev step */ data = _enc_word << 24; _encode_data( wordA, 8 ); data |= _enc_word << 14; _encode_data( wordB, 24 ); data |= _enc_word << 4; _encode_data( wordB, 16 ); data |= _enc_word >> 6; break; // |7:1| 1 |7:1|7:1|7:1|7:1| 1 |7:2|7:2|7:2|7:2| 1 |7:2|7:2|7:2|7:2| // | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |ub0|ub1|ub2|ub3| case 7: /* Word from prev step */ data = _enc_word << 26; _encode_data( wordA, 8 ); data |= _enc_word << 16; // TODO - encode user data rather than hard-coding zeros //if( _enc_word & 1 ) _tx_carry = data |= 0b0000000000011111; if( _enc_word & 1 ) data |= 0b0000000000011111; else _enc_word = data |= 0b1111111111100000; _enc_word = data; break; } _xperipherals_adat_tx_2__port_txd <: bitrev( data ); } #elif XPERIPHERALS_ADAT_TX_2__BCLK_SPEED == 4 #endif #endif
#include <xs1.h> #include <platform.h> #include <xclib.h> #include <print.h> #include <stdio.h> #include "xperipherals_adat.h" // 256-Bit ADAT Packet // // The packet structure below shows [Channel Number]:[Sample Bit Pos] for audio samples. // The 256-bit sequence is NRZI encoded when transmitting and NRZI decoded when receiving. // Samples are serialized MSB first (:00 represents MSB and :23 represents LSB) // // Note: Bit stuffing with 'ones' every fifth bit and NRZI encoding prevents long runs // of zeros. The zero's at the end of the frame are used for frame synchronization. // // 0 |one |0:00|0:01|0:02|0:03|one |0:04|0:05|0:06|0:07|one |0:08|0:09|0:10|0:11|one | // |0:12|0:13|0:14|0:15|one |0:16|0:17|0:18|0:19|one |0:20|0:21|0:22|0:23|one |1:00| // 1 |1:01|1:02|1:03|one |1:04|1:05|1:06|1:07|one |1:08|1:09|1:10|1:11|one |1:12|1:13| // |1:14|1:15|one |1:16|1:17|1:18|1:19|one |1:20|1:21|1:22|1:23|one |2:00|2:01|2:02| // 2 |2:03|one |2:04|2:05|2:06|2:07|one |2:08|2:09|2:10|2:11|one |2:12|2:13|2:14|2:15| // |one |2:16|2:17|2:18|2:19|one |2:20|2:21|2:22|2:23|one |3:00|3:01|3:02|3:03|one | // 3 |3:04|3:05|3:06|3:07|one |3:08|3:09|3:10|3:11|one |3:12|3:13|3:14|3:15|one |3:16| // |3:17|3:18|3:19|one |3:20|3:21|3:22|3:23|one |4:00|4:01|4:02|4:03|one |4:04|4:05| // 4 |4:06|4:07|one |4:08|4:09|4:10|4:11|one |4:12|4:13|4:14|4:15|one |4:16|4:17|4:18| // |4:19|one |4:20|4:21|4:22|4:23|one |5:00|5:01|5:02|5:03|one |5:04|5:05|5:06|5:07| // 5 |one |5:08|5:09|5:10|5:11|one |5:12|5:13|5:14|5:15|one |5:16|5:17|5:18|5:19|one | // |5:20|5:21|5:22|5:23|one |6:00|6:01|6:02|6:03|one |6:04|6:05|6:06|6:07|one |6:08| // 6 |6:09|6:10|6:11|one |6:12|6:13|6:14|6:15|one |6:16|6:17|6:18|6:19|one |6:20|6:21| // |6:22|6:23|one |7:00|7:01|7:02|7:03|one |7:04|7:05|7:06|7:07|one |7:08|7:09|7:10| // 7 |7:11|one |7:12|7:13|7:14|7:15|one |7:16|7:17|7:18|7:19|one |7:20|7:21|7:22|7:23| // |one |zero|zero|zero|zero|zero|zero|zero|zero|zero|zero|one |usr0|usr1|usr2|usr3| #ifdef XPERIPHERALS_ADAT_RX_1 on tile[XPERIPHERALS_ADAT_RX_1__TILE_NUMBER] : out buffered port:32 _xperipherals_adat_rx_1__port_rxd = XPERIPHERALS_ADAT_RX_1__RXD_PORT; static xuint _bclk_divider; static xuint _encode_lut[256]; static xuint _enc_word; static xuint _tx_carry; void xperipherals_adat_rx_1__init( xuint bclk_divider ) { _bclk_divider = bclk_divider; _enc_word = _tx_carry = 0; switch( _bclk_divider ) { case 1: // bit clock frequency = 1 * ADAT bit rate = 12.288 / 11.2896 MHz for( int j = 0; j < 256; ++j ) { xuint carry = 0; xuint data = 0b1000010000 | ((j & 0xF0) << 1) | (j & 0x0F); _encode_lut[j] = 0; for( int i = 0; i < 10; ++i, data <<= 1 ) { if( data & 0b1000000000 ) carry = !carry; _encode_lut[j] = (_encode_lut[j] << 1) | carry; } } break; case 2: // bit clock frequency = 2 * ADAT bit rate = 24.576 / 22.5792 MHz // TODO break; case 4: // bit clock frequency = 4 * ADAT bit rate = 49.152 / 45.1584 MHz // TODO break; } } void xperipherals_adat_rx_1__config( clock bit_clock ) { configure_out_port_no_ready( _xperipherals_adat_rx_1__port_rxd, bit_clock, 0 ); clearbuf( _xperipherals_adat_rx_1__port_rxd ); } #pragma unsafe arrays static void _decode_data( xuint sample, xuint shift ) { } // |one |0:00|0:01|0:02|0:03|one |0:04|0:05|0:06|0:07|one |0:08|0:09|0:10|0:11|one | // |0:12|0:13|0:14|0:15|one |0:16|0:17|0:18|0:19|one |0:20|0:21|0:22|0:23|one |1:00| void xperipherals_adat_rx_1__phase0( xsint& sample_0, xsint& sample_1 ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } // |1:01|1:02|1:03|one |1:04|1:05|1:06|1:07|one |1:08|1:09|1:10|1:11|one |1:12|1:13| // |1:14|1:15|one |1:16|1:17|1:18|1:19|one |1:20|1:21|1:22|1:23|one |2:00|2:01|2:02| void xperipherals_adat_rx_1__phase1( xsint& sample_1, xsint& sample_2 ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } // |2:03|one |2:04|2:05|2:06|2:07|one |2:08|2:09|2:10|2:11|one |2:12|2:13|2:14|2:15| // |one |2:16|2:17|2:18|2:19|one |2:20|2:21|2:22|2:23|one |3:00|3:01|3:02|3:03|one | void xperipherals_adat_rx_1__phase2( xsint& sample_2, xsint& sample_3 ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } // |3:04|3:05|3:06|3:07|one |3:08|3:09|3:10|3:11|one |3:12|3:13|3:14|3:15|one |3:16| // |3:17|3:18|3:19|one |3:20|3:21|3:22|3:23|one |4:00|4:01|4:02|4:03|one |4:04|4:05| void xperipherals_adat_rx_1__phase3( xsint& sample_3, xsint& sample_4 ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } // |4:06|4:07|one |4:08|4:09|4:10|4:11|one |4:12|4:13|4:14|4:15|one |4:16|4:17|4:18| // |4:19|one |4:20|4:21|4:22|4:23|one |5:00|5:01|5:02|5:03|one |5:04|5:05|5:06|5:07| void xperipherals_adat_rx_1__phase4( xsint& sample_4, xsint& sample_5 ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } // |one |5:08|5:09|5:10|5:11|one |5:12|5:13|5:14|5:15|one |5:16|5:17|5:18|5:19|one | // |5:20|5:21|5:22|5:23|one |6:00|6:01|6:02|6:03|one |6:04|6:05|6:06|6:07|one |6:08| void xio_adat_tx_1__phase5( xsint& sample_5, xsint& sample_6 ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } // |6:09|6:10|6:11|one |6:12|6:13|6:14|6:15|one |6:16|6:17|6:18|6:19|one |6:20|6:21| // |6:22|6:23|one |7:00|7:01|7:02|7:03|one |7:04|7:05|7:06|7:07|one |7:08|7:09|7:10| void xio_adat_tx_1__phase6( xsint& sample_6, xsint& sample_7 ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } // |7:11|one |7:12|7:13|7:14|7:15|one |7:16|7:17|7:18|7:19|one |7:20|7:21|7:22|7:23| // |one |zero|zero|zero|zero|zero|zero|zero|zero|zero|zero|one |Usr0|Usr1|Usr2|Usr3| void xio_adat_tx_1__phase7( xsint& sample_7, xuint& userdata ) { xuint data; _xperipherals_adat_rx_1__port_rxd :> data; data = bitrev( data ); } #endif
#include <xs1.h> #include <platform.h> #include <xclib.h> #include <print.h> #include <stdio.h> #include "xperipherals_adat.h" // 256-Bit ADAT Packet // // The packet structure below shows [Channel Number]:[Sample Bit Pos] for audio samples. // The 256-bit sequence is NRZI encoded when transmitting and NRZI decoded when receiving. // Samples are serialized MSB first (:00 represents MSB and :23 represents LSB) // // Note: Bit stuffing with 'ones' every fifth bit and NRZI encoding prevents long runs // of zeros. The zero's at the end of the frame are used for frame synchronization. // // 0 |one |0:00|0:01|0:02|0:03|one |0:04|0:05|0:06|0:07|one |0:08|0:09|0:10|0:11|one | // |0:12|0:13|0:14|0:15|one |0:16|0:17|0:18|0:19|one |0:20|0:21|0:22|0:23|one |1:00| // 1 |1:01|1:02|1:03|one |1:04|1:05|1:06|1:07|one |1:08|1:09|1:10|1:11|one |1:12|1:13| // |1:14|1:15|one |1:16|1:17|1:18|1:19|one |1:20|1:21|1:22|1:23|one |2:00|2:01|2:02| // 2 |2:03|one |2:04|2:05|2:06|2:07|one |2:08|2:09|2:10|2:11|one |2:12|2:13|2:14|2:15| // |one |2:16|2:17|2:18|2:19|one |2:20|2:21|2:22|2:23|one |3:00|3:01|3:02|3:03|one | // 3 |3:04|3:05|3:06|3:07|one |3:08|3:09|3:10|3:11|one |3:12|3:13|3:14|3:15|one |3:16| // |3:17|3:18|3:19|one |3:20|3:21|3:22|3:23|one |4:00|4:01|4:02|4:03|one |4:04|4:05| // 4 |4:06|4:07|one |4:08|4:09|4:10|4:11|one |4:12|4:13|4:14|4:15|one |4:16|4:17|4:18| // |4:19|one |4:20|4:21|4:22|4:23|one |5:00|5:01|5:02|5:03|one |5:04|5:05|5:06|5:07| // 5 |one |5:08|5:09|5:10|5:11|one |5:12|5:13|5:14|5:15|one |5:16|5:17|5:18|5:19|one | // |5:20|5:21|5:22|5:23|one |6:00|6:01|6:02|6:03|one |6:04|6:05|6:06|6:07|one |6:08| // 6 |6:09|6:10|6:11|one |6:12|6:13|6:14|6:15|one |6:16|6:17|6:18|6:19|one |6:20|6:21| // |6:22|6:23|one |7:00|7:01|7:02|7:03|one |7:04|7:05|7:06|7:07|one |7:08|7:09|7:10| // 7 |7:11|one |7:12|7:13|7:14|7:15|one |7:16|7:17|7:18|7:19|one |7:20|7:21|7:22|7:23| // |one |zero|zero|zero|zero|zero|zero|zero|zero|zero|zero|one |usr0|usr1|usr2|usr3| #ifdef XPERIPHERALS_ADAT_RX_2 on tile[XPERIPHERALS_ADAT_RX_2__TILE_NUMBER] : out buffered port:32 _xperipherals_adat_rx_2__port_rxd = XPERIPHERALS_ADAT_RX_2__RXD_PORT; static xuint _bclk_divider; static xuint _encode_lut[256]; static xuint _enc_word; static xuint _tx_carry; void xperipherals_adat_rx_2__init( xuint bclk_divider ) { _bclk_divider = bclk_divider; _enc_word = _tx_carry = 0; switch( _bclk_divider ) { case 1: // bit clock frequency = 1 * ADAT bit rate = 12.288 / 11.2896 MHz for( int j = 0; j < 256; ++j ) { xuint carry = 0; xuint data = 0b1000010000 | ((j & 0xF0) << 1) | (j & 0x0F); _encode_lut[j] = 0; for( int i = 0; i < 10; ++i, data <<= 1 ) { if( data & 0b1000000000 ) carry = !carry; _encode_lut[j] = (_encode_lut[j] << 1) | carry; } } break; case 2: // bit clock frequency = 2 * ADAT bit rate = 24.576 / 22.5792 MHz // TODO break; case 4: // bit clock frequency = 4 * ADAT bit rate = 49.152 / 45.1584 MHz // TODO break; } } void xperipherals_adat_rx_2__config( clock bit_clock ) { configure_out_port_no_ready( _xperipherals_adat_rx_2__port_rxd, bit_clock, 0 ); clearbuf( _xperipherals_adat_rx_2__port_rxd ); } #pragma unsafe arrays static void _decode_data( xuint sample, xuint shift ) { } // |one |0:00|0:01|0:02|0:03|one |0:04|0:05|0:06|0:07|one |0:08|0:09|0:10|0:11|one | // |0:12|0:13|0:14|0:15|one |0:16|0:17|0:18|0:19|one |0:20|0:21|0:22|0:23|one |1:00| void xperipherals_adat_rx_2__phase0( xsint& sample_0, xsint& sample_1 ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } // |1:01|1:02|1:03|one |1:04|1:05|1:06|1:07|one |1:08|1:09|1:10|1:11|one |1:12|1:13| // |1:14|1:15|one |1:16|1:17|1:18|1:19|one |1:20|1:21|1:22|1:23|one |2:00|2:01|2:02| void xperipherals_adat_rx_2__phase1( xsint& sample_1, xsint& sample_2 ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } // |2:03|one |2:04|2:05|2:06|2:07|one |2:08|2:09|2:10|2:11|one |2:12|2:13|2:14|2:15| // |one |2:16|2:17|2:18|2:19|one |2:20|2:21|2:22|2:23|one |3:00|3:01|3:02|3:03|one | void xperipherals_adat_rx_2__phase2( xsint& sample_2, xsint& sample_3 ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } // |3:04|3:05|3:06|3:07|one |3:08|3:09|3:10|3:11|one |3:12|3:13|3:14|3:15|one |3:16| // |3:17|3:18|3:19|one |3:20|3:21|3:22|3:23|one |4:00|4:01|4:02|4:03|one |4:04|4:05| void xperipherals_adat_rx_2__phase3( xsint& sample_3, xsint& sample_4 ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } // |4:06|4:07|one |4:08|4:09|4:10|4:11|one |4:12|4:13|4:14|4:15|one |4:16|4:17|4:18| // |4:19|one |4:20|4:21|4:22|4:23|one |5:00|5:01|5:02|5:03|one |5:04|5:05|5:06|5:07| void xperipherals_adat_rx_2__phase4( xsint& sample_4, xsint& sample_5 ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } // |one |5:08|5:09|5:10|5:11|one |5:12|5:13|5:14|5:15|one |5:16|5:17|5:18|5:19|one | // |5:20|5:21|5:22|5:23|one |6:00|6:01|6:02|6:03|one |6:04|6:05|6:06|6:07|one |6:08| void xio_adat_tx_2__phase5( xsint& sample_5, xsint& sample_6 ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } // |6:09|6:10|6:11|one |6:12|6:13|6:14|6:15|one |6:16|6:17|6:18|6:19|one |6:20|6:21| // |6:22|6:23|one |7:00|7:01|7:02|7:03|one |7:04|7:05|7:06|7:07|one |7:08|7:09|7:10| void xio_adat_tx_2__phase6( xsint& sample_6, xsint& sample_7 ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } // |7:11|one |7:12|7:13|7:14|7:15|one |7:16|7:17|7:18|7:19|one |7:20|7:21|7:22|7:23| // |one |zero|zero|zero|zero|zero|zero|zero|zero|zero|zero|one |Usr0|Usr1|Usr2|Usr3| void xio_adat_tx_2__phase7( xsint& sample_7, xuint& userdata ) { xuint data; _xperipherals_adat_rx_2__port_rxd :> data; data = bitrev( data ); } #endif