<TODO>
<TODO>
<TODO>
<TODO>
<TODO>
xperipherals_spdif.h SPDIF peripheral interface xperipherals_spdif_1.xc SPDIF peripheral #1 implementation xperipherals_spdif_2.xc SPDIF peripheral #2 implementation
#ifndef XPERIPHERALS_SPDIF__INCLUDED #define XPERIPHERALS_SPDIF__INCLUDED #include "xsystem_types.h" // These must be defined in "xconfig.h" for each peripheral bus being used // // USES_XPERIPHERALS_SPDIF_n No value // // XPERIPHERALS_SPDIF_n__SUPPORT_TX TRUE or FALSE // XPERIPHERALS_SPDIF_n__SUPPORT_RX TRUE or FALSE // XPERIPHERALS_SPDIF_n__TILE_NUMBER integer, XS1 tile number // XPERIPHERALS_SPDIF_n__TXD_PORT XS1 port identifier // XPERIPHERALS_SPDIF_n__RXD_PORT XS1 port identifier // Stereo Data Transfer Sequence for One Audio Cycle. // // Note: Two transfers (BEG and END) are required to complete a full sample I/O. // Note: The output data and input data represent the four non-audio bits in the SPDIF sub-frame // // transfer_beg( left output sample, left output data, left input data ref ); // transfer_end( left input sample ref, left output data, left input data ref ); // transfer_beg( right output sample, right output data, right input data ref ); // transfer_end( right input sample ref, right output data, right input data ref ); // // Stereo Data Transfer Sequence for Combined I2S and SPDIF with Same Sample Rates (One Audio Cycle) #define XPERIPHERALS_SPDIF__INTERFACE( N ) \ \ void xperipherals_spdif_##N##__initialize ( void ); \ void xperipherals_spdif_##N##__configure ( clock bit_clock ); \ void xperipherals_spdif_##N##__transfer_beg( xsint tx_sample, xuint tx_data, xuint& rx_data ); \ void xperipherals_spdif_##N##__transfer_end( xsint& rx_sample, xuint tx_data, xuint& rx_data ); XPERIPHERALS_SPDIF__INTERFACE( 1 ) XPERIPHERALS_SPDIF__INTERFACE( 2 ) #endif
#include <xs1.h> #include <platform.h> #include <xclib.h> #include <print.h> #include <stdio.h> #include "xperipherals_spdif.h" #ifdef XPERIPHERALS_SPDIF_1 extern in port master_audio_clock_port; extern clock master_audio_clock_block; #if XPERIPHERALS_SPDIF_1__SUPPORT_TX on tile[XPERIPHERALS_SPDIF_1__TILE_NUMBER] : out buffered port:32 _xperipherals_spdif_1__tx_port = XPERIPHERALS_SPDIF_1__TXD_PORT; #endif #if XPERIPHERALS_SPDIF_1__SUPPORT_RX on tile[XPERIPHERALS_SPDIF_1__TILE_NUMBER] : in buffered port:32 _xperipherals_spdif_1__rx_port = XPERIPHERALS_SPDIF_1__RXD_PORT; #endif static xuint _xperipherals_spdif_1__frame = 0; static xuint _xperipherals_spdif_1__tx_flags = 0; static xuint _xperipherals_spdif_1__rx_flags = 0; #if XPERIPHERALS_SPDIF_1__SUPPORT_TX static xuint _xperipherals_spdif_1__tx_data = 0; #endif #if XPERIPHERALS_SPDIF_1__SUPPORT_RX static xuint _xperipherals_spdif_1__rx_data = 0; #endif static xuint _xperipherals_spdif_1__syncstate = 0; static xuint _xperipherals_spdif_1__synctime; #if XPERIPHERALS_SPDIF_1__SUPPORT_TX xuint _xperipherals_spdif_1__encode[2][16] = {{ 0b11001100, 0b11001101, 0b11001011, 0b11001010, 0b11010011, 0b11010010, 0b11010100, 0b11010101, 0b10110011, 0b10110010, 0b10110100, 0b10110101, 0b10101100, 0b10101101, 0b10101011, 0b10101010, },{ 0b00110011, 0b00110010, 0b00110100, 0b00110101, 0b00101100, 0b00101101, 0b00101011, 0b00101010, 0b01001100, 0b01001101, 0b01001011, 0b01001010, 0b01010011, 0b01010010, 0b01010100, 0b01010101, }}; #endif xuint _xperipherals_spdif_1__header_1 [2] = {0b11101000, 0b00010111}; xuint _xperipherals_spdif_1__header_N[2][2] = {{0b11100010, 0b00011101},{0b11100100,0b00011011}}; #if XPERIPHERALS_SPDIF_1__SUPPORT_RX xuint _xperipherals_spdif_1__decode[256] = { 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0111, 0b0110, 0b0100, 0b0101, 0b0000, 0b0000, 0b0000, 0b0000, 0b0001, 0b0000, 0b0010, 0b0011, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b1011, 0b1010, 0b1000, 0b1001, 0b0000, 0b0000, 0b0000, 0b0000, 0b1101, 0b1100, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b1111, 0b1110, 0b1100, 0b1101, 0b0000, 0b0000, 0b0000, 0b0000, 0b1001, 0b1000, 0b1010, 0b1011, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0011, 0b0010, 0b0000, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, 0b0101, 0b0100, 0b0110, 0b0111, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, }; #endif xbyte _xperipherals_spdif_1__parity[256] = { 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1, }; xbool _xperipherals_spdif_1__calc_parity( xuint data ) { return _xperipherals_spdif_1__parity[ (xbyte)(data >> 24) ] ^ _xperipherals_spdif_1__parity[ (xbyte)(data >> 16) ] ^ _xperipherals_spdif_1__parity[ (xbyte)(data >> 8) ] ^ _xperipherals_spdif_1__parity[ (xbyte)(data >> 0) ]; } void XPERIPHERALS_spdif_1__initialize( void ) { _xperipherals_spdif_1__frame = 0; _xperipherals_spdif_1__syncstate = 1; } void XPERIPHERALS_spdif_1__configure( clock bit_clock ) { #if XPERIPHERALS_SPDIF_1__SUPPORT_TX configure_out_port_no_ready( _xperipherals_spdif_1__tx_port, bit_clock, 0 ); clearbuf( _xperipherals_spdif_1__tx_port ); #endif #if XPERIPHERALS_SPDIF_1__SUPPORT_RX configure_in_port_no_ready( _xperipherals_spdif_1__rx_port, bit_clock ); clearbuf( _xperipherals_spdif_1__rx_port ); #endif } #if XPERIPHERALS_SPDIF_1__SUPPORT_RX void XPERIPHERALS_spdif_1__synchronize( xuint phase ) { _xperipherals_spdif_1__syncstate = 0; return; if( _xperipherals_spdif_1__syncstate == 1 ) { _xperipherals_spdif_1__rx_port :> _xperipherals_spdif_1__rx_data @ _xperipherals_spdif_1__synctime; _xperipherals_spdif_1__synctime += 32; _xperipherals_spdif_1__syncstate++; } // Find a subframe - look for subrame header and skip one clock cycle per sub-frame // to account for headers on non 32-bit boundaries. else if( _xperipherals_spdif_1__syncstate == 2 ) { _xperipherals_spdif_1__rx_port :> _xperipherals_spdif_1__rx_data @ _xperipherals_spdif_1__synctime; _xperipherals_spdif_1__rx_data = bitrev( _xperipherals_spdif_1__rx_data ) >> 24; if( _xperipherals_spdif_1__rx_data == 0xE8 || _xperipherals_spdif_1__rx_data == 0xE2 || _xperipherals_spdif_1__rx_data == 0x17 || _xperipherals_spdif_1__rx_data == 0x1D ) { _xperipherals_spdif_1__synctime += 32; if( phase != 0 ) _xperipherals_spdif_1__synctime += 32; _xperipherals_spdif_1__syncstate = 3; } else if( _xperipherals_spdif_1__rx_data == 0xE4 || _xperipherals_spdif_1__rx_data == 0x1B ) { _xperipherals_spdif_1__synctime += 32; if( phase != 1 ) _xperipherals_spdif_1__synctime += 32; _xperipherals_spdif_1__syncstate = 3; } else _xperipherals_spdif_1__synctime += 33; } // Traverse sub-frames and synchronize to the first sub-frame (find sub-frame #1) else if( _xperipherals_spdif_1__syncstate == 3 ) { _xperipherals_spdif_1__rx_port :> _xperipherals_spdif_1__rx_data @ _xperipherals_spdif_1__synctime; _xperipherals_spdif_1__rx_data = bitrev( _xperipherals_spdif_1__rx_data ) >> 24; if( phase == 0 && (_xperipherals_spdif_1__rx_data == 0xE8 || _xperipherals_spdif_1__rx_data == 0x17) ) { asm("setpt res[%0], %1"::"r"(_xperipherals_spdif_1__rx_port),"r"(_xperipherals_spdif_1__synctime+32)); _xperipherals_spdif_1__syncstate = 0; } _xperipherals_spdif_1__synctime += 32; } } #endif // last=0, pre=B, word=000000000000 --> 11101000 11001100 11001100 11001100 = E8CCCCCC // pre=B, word=000000000000, f=0001 --> 11100100 11001100 11001100 11001101 = CCCCCCCD // last=1, pre=W, word=000000000000 --> 00011011 00110011 00110011 00110011 = 1B333333 // pre=W, word=000000000000, f=0001 --> 00110011 00110011 00110011 00110010 = 33333332 // last=0, pre=M, word=000000000000 --> 11100010 11001100 11001100 11001100 = E2CCCCCC // pre=M, word=000000000000, f=0001 --> 11100100 11001100 11001100 11001101 = CCCCCCCD // last=1, pre=W, word=000000000000 --> 00011011 00110011 00110011 00110011 = 1B333333 // pre=W, word=000000000000, f=0001 --> 00110011 00110011 00110011 00110010 = 33333332 // last=1, pre=B, word=000000000000 --> 00010111 00110011 00110011 00110011 = 17333333 // pre=B, word=000000000000, f=0001 --> 00110011 00110011 00110011 00110010 = 33333332 // last=0, pre=W, word=000000000000 --> 11100100 11001100 11001100 11001100 = E4CCCCCC // pre=W, word=000000000000, f=0001 --> 11001100 11001100 11001100 11001101 = CCCCCCCD // last=1, pre=M, word=000000000000 --> 00011101 00110011 00110011 00110011 = 1D333333 // pre=M, word=000000000000, f=0001 --> 00110011 00110011 00110011 00110010 = 33333332 // last=0, pre=W, word=000000000000 --> 11100100 11001100 11001100 11001100 = E4CCCCCC // pre=W, word=000000000000, f=0001 --> 11001100 11001100 11001100 11001101 = CCCCCCCD void _xperipherals_spdif_1__phase1_write( xuint tx_value ) { // Encode and transmit first 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_1__SUPPORT_TX if( _xperipherals_spdif_1__frame == 0 ) _xperipherals_spdif_1__tx_data = _xperipherals_spdif_1__header_1[_xperipherals_spdif_1__tx_data & 1]; else _xperipherals_spdif_1__tx_data = _xperipherals_spdif_1__header_N[_xperipherals_spdif_1__frame & 1][_xperipherals_spdif_1__tx_data & 1]; _xperipherals_spdif_1__tx_data = (_xperipherals_spdif_1__tx_data << 24) + (_xperipherals_spdif_1__encode[_xperipherals_spdif_1__tx_data & 1][(tx_value >> 28) & 15] << 16) + (_xperipherals_spdif_1__encode[_xperipherals_spdif_1__tx_data & 1][(tx_value >> 24) & 15] << 8) + (_xperipherals_spdif_1__encode[_xperipherals_spdif_1__tx_data & 1][(tx_value >> 20) & 15] << 0); _xperipherals_spdif_1__tx_port <: bitrev( _xperipherals_spdif_1__tx_data ); printf( "%05i 1 %08X\n", _xperipherals_spdif_1__frame, _xperipherals_spdif_1__tx_data ); #endif } void _xperipherals_spdif_1__phase2_write( xuint tx_value ) { // Encode and transmit second 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_1__SUPPORT_TX _xperipherals_spdif_1__tx_data = (_xperipherals_spdif_1__encode[_xperipherals_spdif_1__tx_data & 1][(tx_value >> 16) & 15] << 24) + (_xperipherals_spdif_1__encode[_xperipherals_spdif_1__tx_data & 1][(tx_value >> 12) & 15] << 16) + (_xperipherals_spdif_1__encode[_xperipherals_spdif_1__tx_data & 1][(tx_value >> 8) & 15] << 8) + (_xperipherals_spdif_1__encode[_xperipherals_spdif_1__tx_data & 1][(tx_value >> 0) & 15] << 0); _xperipherals_spdif_1__tx_port <: bitrev( _xperipherals_spdif_1__tx_data ); printf( "%05i 2 %08X\n", _xperipherals_spdif_1__frame, _xperipherals_spdif_1__tx_data ); #endif } void _xperipherals_spdif_1__phase1_read( xuint& rx_sample ) { // Receive and decode first 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_1__SUPPORT_RX if( _xperipherals_spdif_1__syncstate < 3 ) XPERIPHERALS_spdif_1__synchronize( 0 ); else { _xperipherals_spdif_1__rx_port :> _xperipherals_spdif_1__rx_data; _xperipherals_spdif_1__rx_data = bitrev( _xperipherals_spdif_1__rx_data ); //if( (_xperipherals_spdif_1__rx_data >> 28) != 0xE && (_xperipherals_spdif_1__rx_data >> 28) != 0x1 ) { // _xperipherals_spdif_1__syncstate = 1; // return; //} rx_sample = (_xperipherals_spdif_1__decode[(_xperipherals_spdif_1__rx_data >> 16) & 255] << 28) + (_xperipherals_spdif_1__decode[(_xperipherals_spdif_1__rx_data >> 8) & 255] << 24) + (_xperipherals_spdif_1__decode[(_xperipherals_spdif_1__rx_data >> 0) & 255] << 20); } #endif } void _xperipherals_spdif_1__phase2_read( xuint& rx_sample ) { // Receive and decode second 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_1__SUPPORT_RX if( _xperipherals_spdif_1__syncstate < 3 ) XPERIPHERALS_spdif_1__synchronize( 1 ); else { _xperipherals_spdif_1__rx_port :> _xperipherals_spdif_1__rx_data; _xperipherals_spdif_1__rx_data = bitrev( _xperipherals_spdif_1__rx_data ); rx_sample += (_xperipherals_spdif_1__decode[(_xperipherals_spdif_1__rx_data >> 24) & 255] << 16) + (_xperipherals_spdif_1__decode[(_xperipherals_spdif_1__rx_data >> 16) & 255] << 12) + (_xperipherals_spdif_1__decode[(_xperipherals_spdif_1__rx_data >> 8) & 255] << 8); } #endif } xuint _xperipherals_spdif_1__tx_value; xuint _xperipherals_spdif_1__rx_value; void XPERIPHERALS_spdif_1__transfer_beg( xsint tx_sample, xuint tx_data, xuint& rx_data ) { _xperipherals_spdif_1__tx_value = (tx_sample & ~15) | (tx_data & 15); _xperipherals_spdif_1__tx_flags = 1; _xperipherals_spdif_1__phase1_write( _xperipherals_spdif_1__tx_value ); _xperipherals_spdif_1__phase1_read( _xperipherals_spdif_1__rx_value ); } void XPERIPHERALS_spdif_1__transfer_end( xsint& rx_sample, xuint tx_data, xuint& rx_data ) { _xperipherals_spdif_1__phase2_write( _xperipherals_spdif_1__tx_value ); _xperipherals_spdif_1__phase2_read( _xperipherals_spdif_1__rx_value ); if( ++_xperipherals_spdif_1__frame == 384 ) _xperipherals_spdif_1__frame = 0; rx_sample = _xperipherals_spdif_1__rx_value & ~15; rx_data = _xperipherals_spdif_1__rx_value & 15; } #endif
#include <xs1.h> #include <platform.h> #include <xclib.h> #include <print.h> #include "xperipherals_spdif.h" #ifdef XPERIPHERALS_SPDIF_2 extern in port master_audio_clock_port; extern clock master_audio_clock_block; #if XPERIPHERALS_SPDIF_2__SUPPORT_TX on tile[XPERIPHERALS_SPDIF_2__TILE_NUMBER] : out buffered port:32 _xperipherals_spdif_2__tx_port = XPERIPHERALS_SPDIF_2__TXD_PORT; #endif #if XPERIPHERALS_SPDIF_2__SUPPORT_RX on tile[XPERIPHERALS_SPDIF_2__TILE_NUMBER] : in buffered port:32 _xperipherals_spdif_2__rx_port = XPERIPHERALS_SPDIF_2__RXD_PORT; #endif static xuint _xperipherals_spdif_2__stage = 0; static xuint _xperipherals_spdif_2__subframe = 0; #if XPERIPHERALS_SPDIF_2__SUPPORT_TX static xuint _xperipherals_spdif_2__tx_data = 0; #endif #if XPERIPHERALS_SPDIF_2__SUPPORT_RX static xuint _xperipherals_spdif_2__rx_data = 0; #endif static xuint _xperipherals_spdif_2__syncstate = 0; static xuint _xperipherals_spdif_2__synctime; #if XPERIPHERALS_SPDIF_2__SUPPORT_TX static xuint _xperipherals_spdif_2__lut_encode[2][16] = {{ 0b11001100, 0b11001101, 0b11001011, 0b11001010, 0b11010011, 0b11010010, 0b11010100, 0b11010101, 0b10110011, 0b10110010, 0b10110100, 0b10110101, 0b10101100, 0b10101101, 0b10101011, 0b10101010, },{ 0b00110011, 0b00110010, 0b00110100, 0b00110101, 0b00101100, 0b00101101, 0b00101011, 0b00101010, 0b01001100, 0b01001101, 0b01001011, 0b01001010, 0b01010011, 0b01010010, 0b01010100, 0b01010101, }}; #endif static xuint _xperipherals_spdif_2__lut_header_1 [2] = {0b11101000, 0b00010111}; static xuint _xperipherals_spdif_2__lut_header_N[2][2] = {{0b11100010, 0b00011101}, {0b11100100, 0b00011011}}; #if XPERIPHERALS_SPDIF_2__SUPPORT_RX static xuint _xperipherals_spdif_2__lut_decode[256] = { 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0111,0b0110,0b0100,0b0101,0b0000,0b0000, 0b0000,0b0000,0b0001,0b0000,0b0010,0b0011,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b1011,0b1010,0b1000,0b1001,0b0000,0b0000, 0b0000,0b0000,0b1101,0b1100,0b1110,0b1111,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b1111,0b1110,0b1100,0b1101,0b0000,0b0000, 0b0000,0b0000,0b1001,0b1000,0b1010,0b1011,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0011,0b0010,0b0000,0b0001,0b0000,0b0000, 0b0000,0b0000,0b0101,0b0100,0b0110,0b0111,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, 0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000,0b0000, }; #endif void XPERIPHERALS_spdif_2__initialize( void ) { _xperipherals_spdif_2__subframe = 0; _xperipherals_spdif_2__syncstate = 1; #if XPERIPHERALS_SPDIF_2__SUPPORT_TX configure_out_port_no_ready( _xperipherals_spdif_2__tx_port, master_audio_clock_block, 0 ); clearbuf( _xperipherals_spdif_2__tx_port ); #endif #if XPERIPHERALS_SPDIF_2__SUPPORT_RX configure_in_port_no_ready( _xperipherals_spdif_2__rx_port, master_audio_clock_block ); clearbuf( _xperipherals_spdif_2__rx_port ); #endif } #if XPERIPHERALS_SPDIF_2__SUPPORT_RX static void _xperipherals_spdif_2__synchronize( xuint phase ) { _xperipherals_spdif_2__syncstate = 0; return; if( _xperipherals_spdif_2__syncstate == 1 ) { _xperipherals_spdif_2__rx_port :> _xperipherals_spdif_2__rx_data @ _xperipherals_spdif_2__synctime; _xperipherals_spdif_2__synctime += 32; _xperipherals_spdif_2__syncstate++; } // Find a subframe - look for subrame header and skip one clock cycle per sub-frame to account for // headers on non 32-bit boundaries. else if( _xperipherals_spdif_2__syncstate == 2 ) { _xperipherals_spdif_2__rx_port :> _xperipherals_spdif_2__rx_data @ _xperipherals_spdif_2__synctime; _xperipherals_spdif_2__rx_data = bitrev( _xperipherals_spdif_2__rx_data ) >> 24; if( _xperipherals_spdif_2__rx_data == 0xE8 || _xperipherals_spdif_2__rx_data == 0xE2 || _xperipherals_spdif_2__rx_data == 0x17 || _xperipherals_spdif_2__rx_data == 0x1D ) { _xperipherals_spdif_2__synctime += 32; if( phase != 0 ) _xperipherals_spdif_2__synctime += 32; _xperipherals_spdif_2__syncstate = 3; } else if( _xperipherals_spdif_2__rx_data == 0xE4 || _xperipherals_spdif_2__rx_data == 0x1B ) { _xperipherals_spdif_2__synctime += 32; if( phase != 1 ) _xperipherals_spdif_2__synctime += 32; _xperipherals_spdif_2__syncstate = 3; } else _xperipherals_spdif_2__synctime += 33; } // Traverse sub-frames and synchronize to the first sub-frame (find sub-frame #1) else if( _xperipherals_spdif_2__syncstate == 3 ) { _xperipherals_spdif_2__rx_port :> _xperipherals_spdif_2__rx_data @ _xperipherals_spdif_2__synctime; _xperipherals_spdif_2__rx_data = bitrev( _xperipherals_spdif_2__rx_data ) >> 24; if( phase == 0 && (_xperipherals_spdif_2__rx_data == 0xE8 || _xperipherals_spdif_2__rx_data == 0x17) ) { asm("setpt res[%0], %1"::"r"(_xperipherals_spdif_2__rx_port),"r"(_xperipherals_spdif_2__synctime+32)); _xperipherals_spdif_2__syncstate = 0; } _xperipherals_spdif_2__synctime += 32; } } #endif //#include <stdio.h> //static xuint _xperipherals_spdif_2__trace2_buffer[6][8]; //static xuint _xperipherals_spdif_2__trace2_count = 0; static void _xperipherals_spdif_2__cycle_begin( void ) { } static void _xperipherals_spdif_2__phase1_write( xuint tx_sample ) { // Encode and transmit first 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_2__SUPPORT_TX //_xperipherals_spdif_2__trace2_buffer[0][_xperipherals_spdif_2__trace2_count] = tx_sample; if( _xperipherals_spdif_2__subframe == 0 ) _xperipherals_spdif_2__tx_data = _xperipherals_spdif_2__lut_header_1[_xperipherals_spdif_2__tx_data & 1]; else _xperipherals_spdif_2__tx_data = _xperipherals_spdif_2__lut_header_N[_xperipherals_spdif_2__subframe & 1][_xperipherals_spdif_2__tx_data & 1]; _xperipherals_spdif_2__tx_data = (_xperipherals_spdif_2__tx_data << 24) + (_xperipherals_spdif_2__lut_encode[_xperipherals_spdif_2__tx_data & 1][(tx_sample >> 28) & 15] << 16) + (_xperipherals_spdif_2__lut_encode[_xperipherals_spdif_2__tx_data & 1][(tx_sample >> 24) & 15] << 8) + (_xperipherals_spdif_2__lut_encode[_xperipherals_spdif_2__tx_data & 1][(tx_sample >> 20) & 15] << 0); _xperipherals_spdif_2__tx_port <: bitrev( _xperipherals_spdif_2__tx_data ); //_xperipherals_spdif_2__trace2_buffer[1][_xperipherals_spdif_2__trace2_count] = _xperipherals_spdif_2__tx_data; #endif } static void _xperipherals_spdif_2__phase2_write( xuint tx_sample ) { // Encode and transmit second 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_2__SUPPORT_TX _xperipherals_spdif_2__tx_data = (_xperipherals_spdif_2__lut_encode[_xperipherals_spdif_2__tx_data & 1][(tx_sample >> 16) & 15] << 24) + (_xperipherals_spdif_2__lut_encode[_xperipherals_spdif_2__tx_data & 1][(tx_sample >> 12) & 15] << 16) + (_xperipherals_spdif_2__lut_encode[_xperipherals_spdif_2__tx_data & 1][(tx_sample >> 8) & 15] << 8) + (0 << 0); // <TODO> Flags _xperipherals_spdif_2__tx_port <: bitrev( _xperipherals_spdif_2__tx_data ); //_xperipherals_spdif_2__trace2_buffer[2][_xperipherals_spdif_2__trace2_count] = _xperipherals_spdif_2__tx_data; #endif } static void _xperipherals_spdif_2__phase1_read( xuint& rx_sample ) { // Receive and decode first 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_2__SUPPORT_RX if( _xperipherals_spdif_2__syncstate < 3 ) _xperipherals_spdif_2__synchronize( 0 ); else { _xperipherals_spdif_2__rx_port :> _xperipherals_spdif_2__rx_data; _xperipherals_spdif_2__rx_data = bitrev( _xperipherals_spdif_2__rx_data ); //_xperipherals_spdif_2__trace2_buffer[4][_xperipherals_spdif_2__trace2_count] = _xperipherals_spdif_2__rx_data; // if( (_xperipherals_spdif_2__rx_data >> 28) != 0xE && (_xperipherals_spdif_2__rx_data >> 28) != 0x1 ) {_xperipherals_spdif_2__syncstate = 1; return;} rx_sample = (_xperipherals_spdif_2__lut_decode[(_xperipherals_spdif_2__rx_data >> 16) & 255] << 28) + (_xperipherals_spdif_2__lut_decode[(_xperipherals_spdif_2__rx_data >> 8) & 255] << 24) + (_xperipherals_spdif_2__lut_decode[(_xperipherals_spdif_2__rx_data >> 0) & 255] << 20); } #endif } static void _xperipherals_spdif_2__phase2_read( xuint& rx_sample ) { // Receive and decode second 32-bit portion of BMC encoded 32-bit word #if XPERIPHERALS_SPDIF_2__SUPPORT_RX if( _xperipherals_spdif_2__syncstate < 3 ) _xperipherals_spdif_2__synchronize( 1 ); else { _xperipherals_spdif_2__rx_port :> _xperipherals_spdif_2__rx_data; _xperipherals_spdif_2__rx_data = bitrev( _xperipherals_spdif_2__rx_data ); //_xperipherals_spdif_2__trace2_buffer[5][_xperipherals_spdif_2__trace2_count] = _xperipherals_spdif_2__rx_data; rx_sample += (_xperipherals_spdif_2__lut_decode[(_xperipherals_spdif_2__rx_data >> 24) & 255] << 16) + (_xperipherals_spdif_2__lut_decode[(_xperipherals_spdif_2__rx_data >> 16) & 255] << 12) + (_xperipherals_spdif_2__lut_decode[(_xperipherals_spdif_2__rx_data >> 8) & 255] << 8); } //_xperipherals_spdif_2__trace2_buffer[3][_xperipherals_spdif_2__trace2_count] = rx_sample; #endif } static void _xperipherals_spdif_2__cycle_end( void ) { //if( ++_xperipherals_spdif_2__trace2_count == 8 ) for( int i=0; i<8; ++i ) // printf( "TXD = %08X (%08X:%08X), RXD = %08X (%08X:%08X)\n", // _xperipherals_spdif_2__trace2_buffer[0][i], _xperipherals_spdif_2__trace2_buffer[1][i], _xperipherals_spdif_2__trace2_buffer[2][i], // _xperipherals_spdif_2__trace2_buffer[3][i], _xperipherals_spdif_2__trace2_buffer[4][i], _xperipherals_spdif_2__trace2_buffer[5][i] ); if( ++_xperipherals_spdif_2__subframe == 384 ) _xperipherals_spdif_2__subframe = 0;; } void XPERIPHERALS_spdif_2__transfer_part1( xuint tx_sample, xuint& rx_sample ) { _xperipherals_spdif_2__start_cycle(); _xperipherals_spdif_2__write_phase1( tx_sample ); //_xperipherals_spdif_2__read_phase1( rx_sample ); } void XPERIPHERALS_spdif_2__transfer_part2( xuint tx_sample, xuint& rx_sample ) { _xperipherals_spdif_2__write_phase2( tx_sample ); //_xperipherals_spdif_2__read_phase2( rx_sample ); _xperipherals_spdif_2__end_cycle(); } #endif