#include #include #include #include #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 //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); // 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