diff --git a/examples/AN00202_gige_avb_i2s_demo/src/aem_descriptors.h.in b/examples/AN00202_gige_avb_i2s_demo/src/aem_descriptors.h.in index ad23e639..6626ed4c 100644 --- a/examples/AN00202_gige_avb_i2s_demo/src/aem_descriptors.h.in +++ b/examples/AN00202_gige_avb_i2s_demo/src/aem_descriptors.h.in @@ -64,7 +64,11 @@ unsigned char desc_configuration_0[] = U16(AEM_AVB_INTERFACE_TYPE), U16(1), U16(AEM_CLOCK_SOURCE_TYPE), +#if (AVB_NUM_SINKS > 0) U16(2), +#else + U16(1), +#endif U16(AEM_LOCALE_TYPE), U16(1), U16(AEM_MEMORY_OBJECT_TYPE), @@ -225,7 +229,11 @@ unsigned char desc_stream_port_output_0[] = U16(0), /* number_of_controls */ U16(0), /* base_control */ U16(AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES), /* number_of_clusters */ +#if (AVB_NUM_SINKS > 0) U16(AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS), /* base_cluster */ +#else + U16(0), /* base_cluster */ +#endif U16(1), /* number_of_maps */ U16(1) /* base_map */ }; @@ -437,16 +445,16 @@ unsigned char desc_stream_output_0[] = AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES, // label_mbla_cnt 0, // label_midi_cnt[0:3], label_smptecnt[4:] // 96 - 0x00, 0xa0, 0x04, AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS, + 0x00, 0xa0, 0x04, AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES, 0x40, // b[0], nb[1], reserved[2:] 0, // label_iec_60958_cnt - AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS, // label_mbla_cnt + AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES, // label_mbla_cnt 0, // label_midi_cnt[0:3], label_smptecnt[4:] // 192 - 0x00, 0xa0, 0x06, AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS, + 0x00, 0xa0, 0x06, AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES, 0x40, // b[0], nb[1], reserved[2:] 0, // label_iec_60958_cnt - AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS, // label_mbla_cnt + AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES, // label_mbla_cnt 0 // label_midi_cnt[0:3], label_smptecnt[4:] }; #endif @@ -509,6 +517,7 @@ unsigned char desc_clock_source_0[] = { U16(AEM_CLOCK_SOURCE_TYPE), /* 0-1 descriptor_type */ U16(0), /* 2-3 descriptor_id */ +#if (AVB_NUM_SINKS > 0) "Input Stream", /* 4-67 object_name */ U16(AEM_NO_STRING), /* 68-69 localized_description */ U16(AEM_CLOCK_SOURCE_FLAGS_LOCAL_ID), /* 70-71 clock_source_flags */ @@ -522,6 +531,7 @@ unsigned char desc_clock_source_1[] = { U16(AEM_CLOCK_SOURCE_TYPE), /* 0-1 descriptor_type */ U16(1), /* 2-3 descriptor_id */ +#endif "Internal Clock", /* 4-67 object_name */ U16(AEM_NO_STRING), /* 68-69 localized_description */ U16(0), /* 70-71 clock_source_flags */ @@ -601,7 +611,11 @@ unsigned int aem_descriptor_list[] = AEM_JACK_INPUT_TYPE, 1, sizeof(desc_jack_input_0), (unsigned)desc_jack_input_0, AEM_JACK_OUTPUT_TYPE, 1, sizeof(desc_jack_output_0), (unsigned)desc_jack_output_0, AEM_AVB_INTERFACE_TYPE, 1, sizeof(desc_avb_interface_0), (unsigned)desc_avb_interface_0, +#if (AVB_NUM_SINKS > 0) AEM_CLOCK_SOURCE_TYPE, 2, sizeof(desc_clock_source_0), (unsigned)desc_clock_source_0, sizeof(desc_clock_source_1), (unsigned)desc_clock_source_1, +#else + AEM_CLOCK_SOURCE_TYPE, 1, sizeof(desc_clock_source_0), (unsigned)desc_clock_source_0, +#endif AEM_MEMORY_OBJECT_TYPE, 1, sizeof(desc_upgrade_image_memory_object_0), (unsigned)desc_upgrade_image_memory_object_0, AEM_LOCALE_TYPE, 1, sizeof(desc_locale_0), (unsigned)desc_locale_0, AEM_STRINGS_TYPE, 1, sizeof(desc_strings_0), (unsigned)desc_strings_0, diff --git a/examples/AN00202_gige_avb_i2s_demo/src/main.xc b/examples/AN00202_gige_avb_i2s_demo/src/main.xc index 8e6f954f..9bde827c 100644 --- a/examples/AN00202_gige_avb_i2s_demo/src/main.xc +++ b/examples/AN00202_gige_avb_i2s_demo/src/main.xc @@ -44,7 +44,9 @@ on tile[0]: out buffered port:32 p_fs[1] = { XS1_PORT_1A }; // Low frequency PLL on tile[0]: out buffered port:32 p_i2s_lrclk = XS1_PORT_1G; on tile[0]: out buffered port:32 p_i2s_bclk = XS1_PORT_1H; on tile[0]: in port p_i2s_mclk = XS1_PORT_1F; +#if AVB_NUM_MEDIA_OUTPUTS on tile[0]: out buffered port:32 p_aud_dout[4] = {XS1_PORT_1M, XS1_PORT_1N, XS1_PORT_1O, XS1_PORT_1P}; +#endif on tile[0]: in buffered port:32 p_aud_din[4] = {XS1_PORT_1I, XS1_PORT_1J, XS1_PORT_1K, XS1_PORT_1L}; on tile[0]: clock clk_i2s_bclk = XS1_CLKBLK_3; on tile[0]: clock clk_i2s_mclk = XS1_CLKBLK_4; @@ -93,7 +95,9 @@ on tile[0]: out port p_audio_shared = XS1_PORT_8C; void buffer_manager_to_i2s(server i2s_callback_if i2s, streaming chanend c_audio, client interface i2c_master_if i2c, +#if AVB_NUM_MEDIA_OUTPUTS streaming chanend c_sound_activity, +#endif int synth_sinewave_channel_mask, client output_gpio_if dac_reset, client output_gpio_if adc_reset, @@ -102,15 +106,20 @@ void buffer_manager_to_i2s(server i2s_callback_if i2s, { audio_frame_t *unsafe p_in_frame; audio_double_buffer_t *unsafe double_buffer; +#if AVB_NUM_MEDIA_OUTPUTS int32_t *unsafe sample_out_buf; - unsigned cur_sample_rate; const int sound_activity_threshold = 100000; const int sound_activity_update_interval = 2500; int sound_activity_update = 0; - int sinewave_index = 0; int channel_mask = 0; +#else + unsigned sample_out_count = 0; +#endif + unsigned cur_sample_rate; + int sinewave_index = 0; timer tmr; + audio_clock_CS2100CP_init(i2c); while (1) { @@ -194,6 +203,7 @@ void buffer_manager_to_i2s(server i2s_callback_if i2s, break; case i2s.restart_check() -> i2s_restart_t restart: +#if AVB_NUM_MEDIA_OUTPUTS unsafe { if (sample_out_buf[8]) { restart = I2S_RESTART; @@ -206,6 +216,9 @@ void buffer_manager_to_i2s(server i2s_callback_if i2s, restart = I2S_NO_RESTART; } } +#else + restart = I2S_NO_RESTART; +#endif break; // End of restart check case i2s.receive(size_t index, int32_t sample): @@ -221,10 +234,23 @@ void buffer_manager_to_i2s(server i2s_callback_if i2s, if (sinewave_index == 256) sinewave_index = 0; } + +#if !AVB_NUM_MEDIA_OUTPUTS + sample_out_count++; + if( sample_out_count == AVB_NUM_MEDIA_INPUTS ) + { + tmr :> p_in_frame->timestamp; + audio_frame_t *unsafe new_frame = audio_buffers_swap_active_buffer(*double_buffer); + c_audio <: p_in_frame; + p_in_frame = new_frame; + sample_out_count = 0; + } +#endif } break; case i2s.send(size_t index) -> int32_t sample: +#if AVB_NUM_MEDIA_OUTPUTS unsafe { if (index == 0) { c_audio :> sample_out_buf; @@ -253,6 +279,7 @@ void buffer_manager_to_i2s(server i2s_callback_if i2s, } } } +#endif break; // End of send } } @@ -261,8 +288,11 @@ void buffer_manager_to_i2s(server i2s_callback_if i2s, [[combinable]] void ar8035_phy_driver(client interface smi_if smi, - client interface ethernet_cfg_if eth, - streaming chanend c_sound_activity) { + client interface ethernet_cfg_if eth +#if AVB_NUM_MEDIA_OUTPUTS + , streaming chanend c_sound_activity +#endif + ) { ethernet_link_state_t link_state = ETHERNET_LINK_DOWN; ethernet_speed_t link_speed = LINK_1000_MBPS_FULL_DUPLEX; const int phy_reset_delay_ms = 1; @@ -318,8 +348,10 @@ void ar8035_phy_driver(client interface smi_if smi, } t += link_poll_period_ms * XS1_TIMER_KHZ; break; +#if AVB_NUM_MEDIA_OUTPUTS case c_sound_activity :> channel_mask: break; +#endif case tmr2 when timerafter(t2) :> void: p_leds_row <: ~(flashing_on * channel_mask); flashing_on ^= 1; @@ -332,13 +364,13 @@ void ar8035_phy_driver(client interface smi_if smi, enum mac_rx_lp_clients { MAC_TO_MEDIA_CLOCK_PTP = 0, MAC_TO_1722_1, - NUM_ETH_TX_LP_CLIENTS + NUM_ETH_RX_LP_CLIENTS }; enum mac_tx_lp_clients { MEDIA_CLOCK_PTP_TO_MAC = 0, AVB1722_1_TO_MAC, - NUM_ETH_RX_LP_CLIENTS + NUM_ETH_TX_LP_CLIENTS }; enum mac_cfg_clients { @@ -389,7 +421,9 @@ int main(void) ethernet_cfg_if i_eth_cfg[NUM_ETH_CFG_CLIENTS]; ethernet_rx_if i_eth_rx_lp[NUM_ETH_RX_LP_CLIENTS]; ethernet_tx_if i_eth_tx_lp[NUM_ETH_TX_LP_CLIENTS]; +#if AVB_NUM_LISTENER_UNITS streaming chan c_eth_rx_hp; +#endif streaming chan c_eth_tx_hp; smi_if i_smi; streaming chan c_rgmii_cfg; @@ -399,8 +433,10 @@ int main(void) // AVB unit control chan c_talker_ctl[AVB_NUM_TALKER_UNITS]; +#if AVB_NUM_LISTENER_UNITS chan c_listener_ctl[AVB_NUM_LISTENER_UNITS]; chan c_buf_ctl[AVB_NUM_LISTENER_UNITS]; +#endif // Media control chan c_media_ctl[AVB_NUM_MEDIA_UNITS]; @@ -419,27 +455,46 @@ int main(void) streaming chan c_audio; interface push_if i_audio_in_push; interface pull_if i_audio_in_pull; +#if AVB_NUM_LISTENER_UNITS interface push_if i_audio_out_push; +#endif +#if AVB_NUM_MEDIA_OUTPUTS || AVB_NUM_LISTENER_UNITS interface pull_if i_audio_out_pull; +#endif +#if AVB_NUM_MEDIA_OUTPUTS streaming chan c_sound_activity; +#endif par { on tile[1]: rgmii_ethernet_mac(i_eth_rx_lp, NUM_ETH_RX_LP_CLIENTS, i_eth_tx_lp, NUM_ETH_TX_LP_CLIENTS, - c_eth_rx_hp, c_eth_tx_hp, +#if AVB_NUM_LISTENER_UNITS + c_eth_rx_hp, +#else + null, +#endif + c_eth_tx_hp, c_rgmii_cfg, rgmii_ports, ETHERNET_DISABLE_SHAPER); on tile[1].core[0]: rgmii_ethernet_mac_config(i_eth_cfg, NUM_ETH_CFG_CLIENTS, c_rgmii_cfg); - on tile[1].core[0]: ar8035_phy_driver(i_smi, i_eth_cfg[MAC_CFG_TO_PHY_DRIVER], c_sound_activity); + on tile[1].core[0]: ar8035_phy_driver(i_smi, i_eth_cfg[MAC_CFG_TO_PHY_DRIVER] +#if AVB_NUM_MEDIA_OUTPUTS + , c_sound_activity +#endif + ); on tile[1]: [[distribute]] smi(i_smi, p_smi_mdio, p_smi_mdc); on tile[0]: gptp_media_clock_server(i_media_clock_ctl, null, +#if AVB_NUM_LISTENER_UNITS c_buf_ctl, +#else + null, +#endif AVB_NUM_LISTENER_UNITS, p_fs, i_eth_rx_lp[MAC_TO_MEDIA_CLOCK_PTP], @@ -456,7 +511,12 @@ int main(void) configure_clock_src(clk_i2s_mclk, p_i2s_mclk); start_clock(clk_i2s_mclk); i2s_master(i_i2s, - p_aud_dout, AVB_NUM_MEDIA_OUTPUTS/2, +#if AVB_NUM_MEDIA_OUTPUTS + p_aud_dout, +#else + null, +#endif + AVB_NUM_MEDIA_OUTPUTS/2, p_aud_din, AVB_NUM_MEDIA_INPUTS/2, p_i2s_bclk, p_i2s_lrclk, @@ -464,10 +524,21 @@ int main(void) clk_i2s_mclk); } - on tile[0]: [[distribute]] buffer_manager_to_i2s(i_i2s, c_audio, i_i2c[I2S_TO_I2C], c_sound_activity, 0xC, + on tile[0]: [[distribute]] buffer_manager_to_i2s(i_i2s, c_audio, i_i2c[I2S_TO_I2C], +#if AVB_NUM_MEDIA_OUTPUTS + c_sound_activity, +#endif + 0xC, i_gpio[0], i_gpio[1], i_gpio[2], i_gpio[3]); - on tile[0]: audio_buffer_manager(c_audio, i_audio_in_push, i_audio_out_pull, c_media_ctl[0], AUDIO_I2S_IO); + on tile[0]: audio_buffer_manager(c_audio, i_audio_in_push, +#if AVB_NUM_MEDIA_OUTPUTS || AVB_NUM_LISTENER_UNITS + i_audio_out_pull, +#else + null, +#endif + c_media_ctl[0], + AUDIO_I2S_IO); on tile[0]: [[distribute]] audio_input_sample_buffer(i_audio_in_push, i_audio_in_pull); @@ -477,7 +548,9 @@ int main(void) AVB_NUM_SOURCES, i_audio_in_pull); - on tile[0]: [[distribute]] audio_output_sample_buffer(i_audio_out_push, i_audio_out_pull); +#if AVB_NUM_LISTENER_UNITS + on tile[0]: [[distribute]] audio_output_sample_buffer(i_audio_out_push, + i_audio_out_pull); on tile[0]: avb_1722_listener(c_eth_rx_hp, c_buf_ctl[0], @@ -485,6 +558,8 @@ int main(void) c_listener_ctl[0], AVB_NUM_SINKS, i_audio_out_push); +#endif + on tile[0]: { char mac_address[6]; @@ -497,7 +572,11 @@ int main(void) avb_manager(i_avb, NUM_AVB_MANAGER_CHANS, null, c_media_ctl, +#if AVB_NUM_LISTENER_UNITS c_listener_ctl, +#else + null, +#endif c_talker_ctl, i_eth_cfg[MAC_CFG_TO_AVB_MANAGER], i_media_clock_ctl); @@ -526,7 +605,11 @@ void application_task(client interface avb_interface avb, unsigned char aem_identify_control_value = 0; // Initialize the media clock +#if (AVB_NUM_SINKS > 0) avb.set_device_media_clock_type(0, DEVICE_MEDIA_CLOCK_INPUT_STREAM_DERIVED); +#else + avb.set_device_media_clock_type(0, DEVICE_MEDIA_CLOCK_LOCAL_CLOCK); +#endif avb.set_device_media_clock_rate(0, default_sample_rate); avb.set_device_media_clock_state(0, DEVICE_MEDIA_CLOCK_STATE_ENABLED); avb.set_device_media_clock_source(0, 0); @@ -542,6 +625,7 @@ void application_task(client interface avb_interface avb, avb.set_source_channels(j, channels_per_stream); } +#if AVB_NUM_SINKS for (int j=0; j < AVB_NUM_SINKS; j++) { const int channels_per_stream = AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS; @@ -552,6 +636,7 @@ void application_task(client interface avb_interface avb, avb.set_sink_sync(j, 0); avb.set_sink_channels(j, channels_per_stream); } +#endif while (1) { diff --git a/examples/AN00203_gige_avb_tdm_demo/src/aem_descriptors.h.in b/examples/AN00203_gige_avb_tdm_demo/src/aem_descriptors.h.in index 25e6a09c..82401a77 100644 --- a/examples/AN00203_gige_avb_tdm_demo/src/aem_descriptors.h.in +++ b/examples/AN00203_gige_avb_tdm_demo/src/aem_descriptors.h.in @@ -64,7 +64,11 @@ unsigned char desc_configuration_0[] = U16(AEM_AVB_INTERFACE_TYPE), U16(1), U16(AEM_CLOCK_SOURCE_TYPE), +#if (AVB_NUM_SINKS > 0) U16(2), +#else + U16(1), +#endif U16(AEM_LOCALE_TYPE), U16(1), U16(AEM_MEMORY_OBJECT_TYPE), @@ -223,7 +227,11 @@ unsigned char desc_stream_port_output_0[] = U16(0), /* number_of_controls */ U16(0), /* base_control */ U16(AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES), /* number_of_clusters */ +#if (AVB_NUM_SINKS > 0) U16(AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS), /* base_cluster */ +#else + U16(0), /* base_cluster */ +#endif U16(1), /* number_of_maps */ U16(1) /* base_map */ }; @@ -483,6 +491,7 @@ unsigned char desc_clock_source_0[] = { U16(AEM_CLOCK_SOURCE_TYPE), /* 0-1 descriptor_type */ U16(0), /* 2-3 descriptor_id */ +#if (AVB_NUM_SINKS > 0) "Input Stream", /* 4-67 object_name */ U16(AEM_NO_STRING), /* 68-69 localized_description */ U16(AEM_CLOCK_SOURCE_FLAGS_LOCAL_ID), /* 70-71 clock_source_flags */ @@ -496,6 +505,7 @@ unsigned char desc_clock_source_1[] = { U16(AEM_CLOCK_SOURCE_TYPE), /* 0-1 descriptor_type */ U16(1), /* 2-3 descriptor_id */ +#endif "Internal Clock", /* 4-67 object_name */ U16(AEM_NO_STRING), /* 68-69 localized_description */ U16(0), /* 70-71 clock_source_flags */ @@ -575,7 +585,11 @@ unsigned int aem_descriptor_list[] = AEM_JACK_INPUT_TYPE, 1, sizeof(desc_jack_input_0), (unsigned)desc_jack_input_0, AEM_JACK_OUTPUT_TYPE, 1, sizeof(desc_jack_output_0), (unsigned)desc_jack_output_0, AEM_AVB_INTERFACE_TYPE, 1, sizeof(desc_avb_interface_0), (unsigned)desc_avb_interface_0, +#if (AVB_NUM_SINKS > 0) AEM_CLOCK_SOURCE_TYPE, 2, sizeof(desc_clock_source_0), (unsigned)desc_clock_source_0, sizeof(desc_clock_source_1), (unsigned)desc_clock_source_1, +#else + AEM_CLOCK_SOURCE_TYPE, 1, sizeof(desc_clock_source_0), (unsigned)desc_clock_source_0, +#endif AEM_MEMORY_OBJECT_TYPE, 1, sizeof(desc_upgrade_image_memory_object_0), (unsigned)desc_upgrade_image_memory_object_0, AEM_LOCALE_TYPE, 1, sizeof(desc_locale_0), (unsigned)desc_locale_0, AEM_STRINGS_TYPE, 1, sizeof(desc_strings_0), (unsigned)desc_strings_0, diff --git a/examples/AN00203_gige_avb_tdm_demo/src/main.xc b/examples/AN00203_gige_avb_tdm_demo/src/main.xc index e31578b7..c9477b2e 100644 --- a/examples/AN00203_gige_avb_tdm_demo/src/main.xc +++ b/examples/AN00203_gige_avb_tdm_demo/src/main.xc @@ -49,7 +49,9 @@ on tile[0]: in port p_tdm_mclk = XS1_PORT_1F; clock clk_tdm_bclk = on tile[0]: XS1_CLKBLK_3; clock clk_tdm_mclk = on tile[0]: XS1_CLKBLK_4; +#if AVB_NUM_MEDIA_OUTPUTS on tile[0]: out buffered port:32 p_aud_dout[4] = {XS1_PORT_1M, XS1_PORT_1N, XS1_PORT_1O, XS1_PORT_1P}; +#endif on tile[0]: in buffered port:32 p_aud_din[4] = {XS1_PORT_1I, XS1_PORT_1J, XS1_PORT_1K, XS1_PORT_1L}; on tile[0]: out port p_audio_shared = XS1_PORT_8C; @@ -96,7 +98,9 @@ on tile[0]: out port p_audio_shared = XS1_PORT_8C; void buffer_manager_to_tdm(server i2s_callback_if tdm, streaming chanend c_audio, client interface i2c_master_if i2c, +#if AVB_NUM_MEDIA_OUTPUTS streaming chanend c_sound_activity, +#endif int synth_sinewave_channel_mask, client output_gpio_if dac_reset, client output_gpio_if adc_reset, @@ -105,15 +109,20 @@ void buffer_manager_to_tdm(server i2s_callback_if tdm, { audio_frame_t *unsafe p_in_frame; audio_double_buffer_t *unsafe double_buffer; +#if AVB_NUM_MEDIA_OUTPUTS int32_t *unsafe sample_out_buf; unsigned send_count = 0; const int sound_activity_threshold = 100000; const int sound_activity_update_interval = 2500; int sound_activity_update = 0; - int sinewave_index = 0; int channel_mask = 0; +#else + unsigned sample_out_count = 0; +#endif + int sinewave_index = 0; timer tmr; + audio_clock_CS2100CP_init(i2c); while (1) { @@ -122,7 +131,9 @@ void buffer_manager_to_tdm(server i2s_callback_if tdm, tdm_config.offset = -1; tdm_config.sync_len = 1; tdm_config.channels_per_frame = 8; +#if AVB_NUM_MEDIA_OUTPUTS send_count = 0; +#endif // Set CODEC in reset dac_reset.output(0); @@ -205,15 +216,29 @@ void buffer_manager_to_tdm(server i2s_callback_if tdm, else { p_in_frame->samples[index] = sample; } + if (synth_sinewave_channel_mask && index == 0) { sinewave_index++; if (sinewave_index == 256) sinewave_index = 0; } + +#if !AVB_NUM_MEDIA_OUTPUTS + sample_out_count++; + if( sample_out_count == AVB_NUM_MEDIA_INPUTS ) + { + tmr :> p_in_frame->timestamp; + audio_frame_t *unsafe new_frame = audio_buffers_swap_active_buffer(*double_buffer); + c_audio <: p_in_frame; + p_in_frame = new_frame; + sample_out_count = 0; + } +#endif } break; case tdm.send(size_t index) -> int32_t sample: +#if AVB_NUM_MEDIA_OUTPUTS unsafe { if (send_count == 0) { c_audio :> sample_out_buf; @@ -244,6 +269,7 @@ void buffer_manager_to_tdm(server i2s_callback_if tdm, } } } +#endif break; // End of send } } @@ -252,8 +278,11 @@ void buffer_manager_to_tdm(server i2s_callback_if tdm, [[combinable]] void ar8035_phy_driver(client interface smi_if smi, - client interface ethernet_cfg_if eth, - streaming chanend c_sound_activity) + client interface ethernet_cfg_if eth +#if AVB_NUM_MEDIA_OUTPUTS + , streaming chanend c_sound_activity +#endif + ) { ethernet_link_state_t link_state = ETHERNET_LINK_DOWN; ethernet_speed_t link_speed = LINK_1000_MBPS_FULL_DUPLEX; @@ -311,8 +340,10 @@ void ar8035_phy_driver(client interface smi_if smi, } t += link_poll_period_ms * XS1_TIMER_KHZ; break; - case c_sound_activity :> channel_mask: +#if AVB_NUM_MEDIA_OUTPUTS + case c_sound_activity :> channel_mask: break; +#endif case tmr2 when timerafter(t2) :> void: p_leds_row <: ~(flashing_on * channel_mask); flashing_on ^= 1; @@ -325,13 +356,13 @@ void ar8035_phy_driver(client interface smi_if smi, enum mac_rx_lp_clients { MAC_TO_MEDIA_CLOCK_PTP = 0, MAC_TO_1722_1, - NUM_ETH_TX_LP_CLIENTS + NUM_ETH_RX_LP_CLIENTS }; enum mac_tx_lp_clients { MEDIA_CLOCK_PTP_TO_MAC = 0, AVB1722_1_TO_MAC, - NUM_ETH_RX_LP_CLIENTS + NUM_ETH_TX_LP_CLIENTS }; enum mac_cfg_clients { @@ -383,7 +414,9 @@ int main(void) ethernet_cfg_if i_eth_cfg[NUM_ETH_CFG_CLIENTS]; ethernet_rx_if i_eth_rx_lp[NUM_ETH_RX_LP_CLIENTS]; ethernet_tx_if i_eth_tx_lp[NUM_ETH_TX_LP_CLIENTS]; +#if AVB_NUM_LISTENER_UNITS streaming chan c_eth_rx_hp; +#endif streaming chan c_eth_tx_hp; smi_if i_smi; streaming chan c_rgmii_cfg; @@ -393,8 +426,10 @@ int main(void) // AVB unit control chan c_talker_ctl[AVB_NUM_TALKER_UNITS]; +#if AVB_NUM_LISTENER_UNITS chan c_listener_ctl[AVB_NUM_LISTENER_UNITS]; chan c_buf_ctl[AVB_NUM_LISTENER_UNITS]; +#endif // Media control chan c_media_ctl[AVB_NUM_MEDIA_UNITS]; @@ -411,27 +446,46 @@ int main(void) streaming chan c_audio; interface push_if i_audio_in_push; interface pull_if i_audio_in_pull; +#if AVB_NUM_LISTENER_UNITS interface push_if i_audio_out_push; +#endif +#if AVB_NUM_MEDIA_OUTPUTS || AVB_NUM_LISTENER_UNITS interface pull_if i_audio_out_pull; +#endif +#if AVB_NUM_MEDIA_OUTPUTS streaming chan c_sound_activity; +#endif par { on tile[1]: rgmii_ethernet_mac(i_eth_rx_lp, NUM_ETH_RX_LP_CLIENTS, i_eth_tx_lp, NUM_ETH_TX_LP_CLIENTS, - c_eth_rx_hp, c_eth_tx_hp, +#if AVB_NUM_LISTENER_UNITS + c_eth_rx_hp, +#else + null, +#endif + c_eth_tx_hp, c_rgmii_cfg, rgmii_ports, ETHERNET_DISABLE_SHAPER); on tile[1].core[0]: rgmii_ethernet_mac_config(i_eth_cfg, NUM_ETH_CFG_CLIENTS, c_rgmii_cfg); - on tile[1].core[0]: ar8035_phy_driver(i_smi, i_eth_cfg[MAC_CFG_TO_PHY_DRIVER], c_sound_activity); + on tile[1].core[0]: ar8035_phy_driver(i_smi, i_eth_cfg[MAC_CFG_TO_PHY_DRIVER] +#if AVB_NUM_MEDIA_OUTPUTS + , c_sound_activity +#endif + ); on tile[1]: [[distribute]] smi(i_smi, p_smi_mdio, p_smi_mdc); on tile[0]: gptp_media_clock_server(i_media_clock_ctl, null, +#if AVB_NUM_LISTENER_UNITS c_buf_ctl, +#else + null, +#endif AVB_NUM_LISTENER_UNITS, p_fs, i_eth_rx_lp[MAC_TO_MEDIA_CLOCK_PTP], @@ -447,14 +501,31 @@ int main(void) configure_clock_src_divide(clk_tdm_bclk, p_tdm_mclk, 1); configure_port_clock_output(p_tdm_bclk, clk_tdm_bclk); - tdm_master(i_tdm, p_tdm_fsync, p_aud_dout, AVB_NUM_MEDIA_OUTPUTS/8, p_aud_din, AVB_NUM_MEDIA_INPUTS/8, + tdm_master(i_tdm, p_tdm_fsync, +#if AVB_NUM_MEDIA_OUTPUTS + p_aud_dout, +#else + null, +#endif + AVB_NUM_MEDIA_OUTPUTS/8, p_aud_din, AVB_NUM_MEDIA_INPUTS/8, clk_tdm_bclk); } - on tile[0]: [[distribute]] buffer_manager_to_tdm(i_tdm, c_audio, i_i2c[I2S_TO_I2C], c_sound_activity, 0x3, + on tile[0]: [[distribute]] buffer_manager_to_tdm(i_tdm, c_audio, i_i2c[I2S_TO_I2C], +#if AVB_NUM_MEDIA_OUTPUTS + c_sound_activity, +#endif + 0x3, i_gpio[0], i_gpio[1], i_gpio[2], i_gpio[3]); - on tile[0]: audio_buffer_manager(c_audio, i_audio_in_push, i_audio_out_pull, c_media_ctl[0], AUDIO_TDM_IO); + on tile[0]: audio_buffer_manager(c_audio, i_audio_in_push, +#if AVB_NUM_MEDIA_OUTPUTS || AVB_NUM_LISTENER_UNITS + i_audio_out_pull, +#else + null, +#endif + c_media_ctl[0], + AUDIO_TDM_IO); on tile[0]: [[distribute]] audio_input_sample_buffer(i_audio_in_push, i_audio_in_pull); @@ -464,7 +535,9 @@ int main(void) AVB_NUM_SOURCES, i_audio_in_pull); - on tile[0]: [[distribute]] audio_output_sample_buffer(i_audio_out_push, i_audio_out_pull); +#if AVB_NUM_LISTENER_UNITS + on tile[0]: [[distribute]] audio_output_sample_buffer(i_audio_out_push, + i_audio_out_pull); on tile[0]: avb_1722_listener(c_eth_rx_hp, c_buf_ctl[0], @@ -472,6 +545,7 @@ int main(void) c_listener_ctl[0], AVB_NUM_SINKS, i_audio_out_push); +#endif on tile[0]: { @@ -485,7 +559,11 @@ int main(void) avb_manager(i_avb, NUM_AVB_MANAGER_CHANS, null, c_media_ctl, +#if AVB_NUM_LISTENER_UNITS c_listener_ctl, +#else + null, +#endif c_talker_ctl, i_eth_cfg[MAC_CFG_TO_AVB_MANAGER], i_media_clock_ctl); @@ -517,7 +595,11 @@ void application_task(client interface avb_interface avb, int t; // Initialize the media clock +#if (AVB_NUM_SINKS > 0) avb.set_device_media_clock_type(0, DEVICE_MEDIA_CLOCK_INPUT_STREAM_DERIVED); +#else + avb.set_device_media_clock_type(0, DEVICE_MEDIA_CLOCK_LOCAL_CLOCK); +#endif avb.set_device_media_clock_rate(0, default_sample_rate); avb.set_device_media_clock_state(0, DEVICE_MEDIA_CLOCK_STATE_ENABLED); avb.set_device_media_clock_source(0, 0); @@ -533,6 +615,7 @@ void application_task(client interface avb_interface avb, avb.set_source_channels(j, channels_per_stream); } +#if AVB_NUM_SINKS for (int j=0; j < AVB_NUM_SINKS; j++) { const int channels_per_stream = AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS; @@ -543,7 +626,7 @@ void application_task(client interface avb_interface avb, avb.set_sink_sync(j, 0); avb.set_sink_channels(j, channels_per_stream); } - +#endif debug_timer :> t; while (1) diff --git a/lib_tsn/api/avb.h b/lib_tsn/api/avb.h index 85c9d4de..ae06a13f 100644 --- a/lib_tsn/api/avb.h +++ b/lib_tsn/api/avb.h @@ -47,7 +47,9 @@ enum device_media_clock_state_t /** The type of source to use as a media clock */ enum device_media_clock_type_t { +#if (AVB_NUM_SINKS > 0) DEVICE_MEDIA_CLOCK_INPUT_STREAM_DERIVED, /*!< The clock is sourced from the media clock of an Input Stream */ +#endif DEVICE_MEDIA_CLOCK_LOCAL_CLOCK /*!< The clock is sourced from within the entity from the local crystal oscillator */ }; @@ -1004,8 +1006,10 @@ extends client interface avb_interface : { info = i._get_media_clock_info(clock_num); info.clock_type = clock_type; debug_printf("Setting clock source:"); - if (info.clock_type) debug_printf(" LOCAL_CLOCK\n"); - else debug_printf(" INPUT_STREAM_DERIVED\n"); + if (info.clock_type == DEVICE_MEDIA_CLOCK_LOCAL_CLOCK) + debug_printf(" LOCAL_CLOCK\n"); + else + debug_printf(" INPUT_STREAM_DERIVED\n"); i._set_media_clock_info(clock_num, info); return 1; } @@ -1196,7 +1200,7 @@ void avb_1722_listener(streaming chanend c_eth_rx_hp, */ void gptp_media_clock_server(server interface media_clock_if media_clock_ctl, chanend ?ptp_svr, - chanend buf_ctl[num_buf_ctl], unsigned num_buf_ctl, + chanend (&?buf_ctl)[num_buf_ctl], unsigned num_buf_ctl, out buffered port:32 p_fs[], client interface ethernet_rx_if i_eth_rx, client interface ethernet_tx_if i_eth_tx, diff --git a/lib_tsn/src/1722/avb_1722_talker.xc b/lib_tsn/src/1722/avb_1722_talker.xc index 9a692281..98248183 100644 --- a/lib_tsn/src/1722/avb_1722_talker.xc +++ b/lib_tsn/src/1722/avb_1722_talker.xc @@ -207,27 +207,34 @@ unsafe void avb_1722_talker_send_packets(streaming chanend c_eth_tx_hp, audio_double_buffer_t &sample_buffer) { volatile audio_double_buffer_t *unsafe p_buffer = (audio_double_buffer_t *unsafe) &sample_buffer; - if (!p_buffer->data_ready) { - return; - } - - unsigned rd_buf = !p_buffer->active_buffer; - audio_frame_t * unsafe frame = (audio_frame_t *)&p_buffer->buffer[rd_buf]; if (st.max_active_avb_stream != -1) { - for (int i=0; i < (st.max_active_avb_stream+1); i++) { - if (st.talker_streams[i].active==2) { // TODO: Replace int with enum - int packet_size = avb1722_create_packet((st.tx_buf[i], unsigned char[]), - st.talker_streams[i], - timeInfo, - frame, i); - if (!st.tx_buf_fill_size[i]) st.tx_buf_fill_size[i] = packet_size; - } - if (i == st.max_active_avb_stream) { - p_buffer->data_ready = 0; + if (p_buffer->data_ready) { + + unsigned rd_buf = !p_buffer->active_buffer; + audio_frame_t * unsafe frame = (audio_frame_t *)&p_buffer->buffer[rd_buf]; + + for (int i=0; i < (st.max_active_avb_stream+1); i++) { + if (st.talker_streams[i].active==2) { // TODO: Replace int with enum + int packet_size = st.tx_buf_fill_size[i]; + if (packet_size) { // Buffer contains queued packet -- send immediately before overwriting data + ethernet_send_hp_packet(c_eth_tx_hp, &(st.tx_buf[i], unsigned char[])[2], packet_size, ETHERNET_ALL_INTERFACES); + st.tx_buf_fill_size[i] = 0; + st.counters.sent_1722++; + } + packet_size = avb1722_create_packet((st.tx_buf[i], unsigned char[]), + st.talker_streams[i], + timeInfo, + frame, i); + if (!st.tx_buf_fill_size[i]) st.tx_buf_fill_size[i] = packet_size; + } + if (i == st.max_active_avb_stream) { + p_buffer->data_ready = 0; + } } } + // Flush queued buffers (one per call to function) for (int i=0; i < (st.max_active_avb_stream+1); i++) { int packet_size = st.tx_buf_fill_size[i]; if (packet_size) { diff --git a/lib_tsn/src/1722/maap/avb_1722_maap.xc b/lib_tsn/src/1722/maap/avb_1722_maap.xc index 8830697a..3ee198c0 100644 --- a/lib_tsn/src/1722/maap/avb_1722_maap.xc +++ b/lib_tsn/src/1722/maap/avb_1722_maap.xc @@ -143,7 +143,7 @@ void avb_1722_maap_request_addresses(int num_addr, char (&?start_address)[]) timeout_val = MAAP_PROBE_INTERVAL_BASE_CS+(maap_addr.base[5]&7); #if AVB_DEBUG_MAAP - debug_printf("MAAP: Set probe interval %d\n", timeout_val*10) + debug_printf("MAAP: Set probe interval %d\n", timeout_val*10); #endif start_avb_timer(maap_timer, timeout_val); } diff --git a/lib_tsn/src/1722_1/avb_1722_1_aecp.c b/lib_tsn/src/1722_1/avb_1722_1_aecp.c index 84ac8548..b7915e8c 100644 --- a/lib_tsn/src/1722_1/avb_1722_1_aecp.c +++ b/lib_tsn/src/1722_1/avb_1722_1_aecp.c @@ -96,8 +96,10 @@ void avb_1722_1_aem_descriptors_init(unsigned int serial_num) { // mac_address in AVB Interface Descriptor desc_avb_interface_0[70+i] = my_mac_addr[i]; +#if (AVB_NUM_SINKS > 0) // clock_source_identifier in clock source descriptor desc_clock_source_0[74+i] = my_mac_addr[i]; +#endif } // TODO: Should be stored centrally, possibly query PTP for ID per interface @@ -193,7 +195,7 @@ static int create_aem_read_descriptor_response(unsigned int read_type, desc_size_bytes = sizeof(aem_desc_audio_cluster_t); } break; -#if (AVB_NUM_SOURCES > 0) +#if (AVB_NUM_SINKS > 0) case AEM_STREAM_INPUT_TYPE: if (read_id < AVB_NUM_SINKS) { descriptor = &desc_stream_input_0[0]; @@ -251,19 +253,25 @@ static int create_aem_read_descriptor_response(unsigned int read_type, { memset(cluster->object_name, 0, 64); strcpy((char *)cluster->object_name, "Input "); +#if (AVB_NUM_SINKS > 0) generate_object_name((char *)cluster->object_name, (int)id_num, AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS); +#else + generate_object_name((char *)cluster->object_name, (int)id_num, 0); +#endif } if (read_type == AEM_STREAM_PORT_OUTPUT_TYPE) { aem_desc_stream_port_input_output_t *stream_port = (aem_desc_stream_port_input_output_t *)descriptor; hton_16(stream_port->base_cluster, AVB_NUM_MEDIA_OUTPUTS + (read_id * AVB_NUM_MEDIA_INPUTS/AVB_NUM_SOURCES)); - hton_16(stream_port->base_map, AVB_NUM_SOURCES + read_id); + hton_16(stream_port->base_map, AVB_NUM_SINKS + read_id); } +#if (AVB_NUM_SINKS > 0) else if (read_type == AEM_STREAM_PORT_INPUT_TYPE) { aem_desc_stream_port_input_output_t *stream_port = (aem_desc_stream_port_input_output_t *)descriptor; hton_16(stream_port->base_cluster, read_id * AVB_NUM_MEDIA_OUTPUTS/AVB_NUM_SINKS); hton_16(stream_port->base_map, read_id); } +#endif found_descriptor = 1; } @@ -298,7 +306,11 @@ static int create_aem_read_descriptor_response(unsigned int read_type, for (int i=0; i < num_mappings; i++) { +#if (AVB_NUM_SINKS > 0) hton_16(audio_map->mappings[i].mapping_stream_index, read_id % AVB_NUM_SINKS); +#else + hton_16(audio_map->mappings[i].mapping_stream_index, read_id); +#endif hton_16(audio_map->mappings[i].mapping_stream_channel, i); hton_16(audio_map->mappings[i].mapping_cluster_offset, i); hton_16(audio_map->mappings[i].mapping_cluster_channel, 0); // Single channel audio clusters diff --git a/lib_tsn/src/1722_1/avb_1722_1_aecp_controls.xc b/lib_tsn/src/1722_1/avb_1722_1_aecp_controls.xc index 8657dac8..7c266fdd 100644 --- a/lib_tsn/src/1722_1/avb_1722_1_aecp_controls.xc +++ b/lib_tsn/src/1722_1/avb_1722_1_aecp_controls.xc @@ -446,7 +446,7 @@ unsafe void process_aem_cmd_startstop_streaming(avb_1722_1_aecp_packet_t *unsafe } else { - if (state == AVB_SINK_STATE_ENABLED) + if (state == AVB_SOURCE_STATE_ENABLED) { avb.set_source_state(stream_index, AVB_SOURCE_STATE_POTENTIAL); } diff --git a/lib_tsn/src/audio_buffering/audio_buffering.h b/lib_tsn/src/audio_buffering/audio_buffering.h index f0e966c7..0c626ed0 100644 --- a/lib_tsn/src/audio_buffering/audio_buffering.h +++ b/lib_tsn/src/audio_buffering/audio_buffering.h @@ -58,7 +58,7 @@ typedef enum audio_io_t void audio_buffer_manager(streaming chanend c_audio, client push_if audio_input_buf, - client pull_if audio_output_buf, + client pull_if? audio_output_buf, chanend c_media_ctrl, const audio_io_t audio_io_type); unsafe void media_ctl_register(chanend media_ctl, diff --git a/lib_tsn/src/audio_buffering/audio_buffering.xc b/lib_tsn/src/audio_buffering/audio_buffering.xc index bc724d46..02e943c3 100644 --- a/lib_tsn/src/audio_buffering/audio_buffering.xc +++ b/lib_tsn/src/audio_buffering/audio_buffering.xc @@ -39,7 +39,7 @@ static void init_audio_input_buffer(audio_double_buffer_t &buffer) buffer.data_ready = 0; } -static void init_audio_output_fifos(struct output_finfo &inf, +void init_audio_output_fifos(struct output_finfo &inf, audio_output_fifo_data_t ofifo_data[], int n) { @@ -50,7 +50,6 @@ static void init_audio_output_fifos(struct output_finfo &inf, } } - [[always_inline]] #pragma unsafe arrays unsafe static audio_frame_t *unsafe audio_buffers_swap_active_buffer(audio_double_buffer_t &buffer); @@ -109,7 +108,7 @@ void audio_output_sample_buffer(server push_if i_push, server pull_if i_pull) #pragma unsafe arrays void audio_buffer_manager(streaming chanend c_audio, client push_if audio_input_buf, - client pull_if audio_output_buf, + client pull_if? audio_output_buf, chanend c_media_ctl, const audio_io_t audio_io_type) { @@ -117,13 +116,19 @@ void audio_buffer_manager(streaming chanend c_audio, buffer_handle_t h_in = audio_input_buf.get_handle(); audio_double_buffer_t *unsafe input_sample_buf = ((struct input_finfo *)h_in)->p_buffer; - buffer_handle_t h_out = audio_output_buf.get_handle(); - audio_output_fifo_t *unsafe output_sample_buf = (audio_output_fifo_t *unsafe)((struct output_finfo *)h_out)->p_buffer; - media_ctl_register(c_media_ctl, AVB_NUM_MEDIA_INPUTS, - output_sample_buf, AVB_NUM_MEDIA_OUTPUTS, 0); + buffer_handle_t h_out = null; + audio_output_fifo_t *unsafe output_sample_buf = null; unsigned ctl_command; unsigned sample_rate; + if( !isnull(audio_output_buf) && AVB_NUM_MEDIA_OUTPUTS ) + { + h_out = audio_output_buf.get_handle(); + output_sample_buf = (audio_output_fifo_t *unsafe)((struct output_finfo *)h_out)->p_buffer; + } + media_ctl_register(c_media_ctl, AVB_NUM_MEDIA_INPUTS, + output_sample_buf, AVB_NUM_MEDIA_OUTPUTS, 0); + c_media_ctl :> ctl_command; c_media_ctl :> sample_rate; @@ -164,30 +169,33 @@ void audio_buffer_manager(streaming chanend c_audio, break; default: - unsafe { - if (audio_io_type == AUDIO_I2S_IO) { - #pragma loop unroll - for (int i=0;i media_clock_info_t info: diff --git a/lib_tsn/src/media_clock/media_clock_server.xc b/lib_tsn/src/media_clock/media_clock_server.xc index 6bc5ccc5..50b49481 100644 --- a/lib_tsn/src/media_clock/media_clock_server.xc +++ b/lib_tsn/src/media_clock/media_clock_server.xc @@ -55,6 +55,7 @@ void update_stream_derived_clocks(int source_num, int locked, int fill) { +#if (AVB_NUM_SINKS > 0) for (int i=0;i 0) for (int i=0;iinfo.clock_type; switch (clock_type) { @@ -121,7 +120,9 @@ unsigned int update_media_clock(chanend ptp_svr, return local_wordlen_to_external_wordlen(clock_info->wordlen); break; +#if (AVB_NUM_SINKS > 0) case DEVICE_MEDIA_CLOCK_INPUT_STREAM_DERIVED: { + long long diff_local; long long ierror, perror; // If the stream info isn't valid at all, then return the default clock rate @@ -159,23 +160,22 @@ unsigned int update_media_clock(chanend ptp_svr, } else perror = ierror - clock_info->ierror; - clock_info->ierror = ierror; + clock_info->ierror = ierror; #if 0 - // These values were tuned for CS2300-CP PLL - clock_info->wordlen = clock_info->wordlen - ((perror / diff_local) * 32) - ((ierror / diff_local) / 4); + // These values were tuned for CS2300-CP PLL + clock_info->wordlen = clock_info->wordlen - ((perror / diff_local) * 32) - ((ierror / diff_local) / 4); #else - // and these for CS2100-CP PLL - clock_info->wordlen = clock_info->wordlen - ((perror / diff_local) * 80)/11 - ((ierror / diff_local) * 1) / 5; + // and these for CS2100-CP PLL + clock_info->wordlen = clock_info->wordlen - ((perror / diff_local) * 80)/11 - ((ierror / diff_local) * 1) / 5; #endif - clock_info->stream_info1 = clock_info->stream_info2; - clock_info->stream_info2.valid = 0; + clock_info->stream_info1 = clock_info->stream_info2; + clock_info->stream_info2.valid = 0; + } } break; - } - - break; +#endif } return local_wordlen_to_external_wordlen(clock_info->wordlen);