diff --git a/applications/stlp/src/usb/adaptive_rate_adjust.c b/applications/stlp/src/usb/adaptive_rate_adjust.c index dee0d8ea..3da6b08d 100644 --- a/applications/stlp/src/usb/adaptive_rate_adjust.c +++ b/applications/stlp/src/usb/adaptive_rate_adjust.c @@ -7,6 +7,9 @@ // Taken from usb_descriptors.c #define USB_AUDIO_EP 0x01 +#include "FreeRTOS.h" +#include "queue.h" + #include "adaptive_rate_adjust.h" #include "adaptive_rate_callback.h" @@ -21,44 +24,64 @@ #include "platform/app_pll_ctrl.h" -bool tud_xcore_data_cb(uint32_t cur_time, uint32_t ep_num, uint32_t ep_dir, size_t xfer_len) -{ - if (ep_num == USB_AUDIO_EP && - ep_dir == USB_DIR_OUT) - { - static uint64_t prev_s; - uint32_t data_rate = determine_USB_audio_rate(cur_time, xfer_len, ep_dir, true); - uint64_t s = (uint64_t)data_rate; +#ifndef USB_ADAPTIVE_TASK_PRIORITY +#define USB_ADAPTIVE_TASK_PRIORITY (configMAX_PRIORITIES-1) +#endif /* USB_ADAPTIVE_TASK_PRIORITY */ + +#define DATA_EVENT_QUEUE_SIZE 1 + +typedef struct usb_audio_rate_packet_desc { + uint32_t cur_time; + uint32_t ep_num; + uint32_t ep_dir; + size_t xfer_len; +} usb_audio_rate_packet_desc_t; + +static QueueHandle_t data_event_queue = NULL; + +static void usb_adaptive_clk_manager(void *args) { + (void) args; + + usb_audio_rate_packet_desc_t pkt_data; + static uint64_t prev_s; + uint32_t data_rate = 0; + uint64_t s = 0; + + while(1) { + xQueueReceive(data_event_queue, (void *)&pkt_data, portMAX_DELAY); + + data_rate = determine_USB_audio_rate(pkt_data.cur_time, pkt_data.xfer_len, pkt_data.ep_dir, true); + s = (uint64_t)data_rate; /* The below manipulations calculate the required f value to scale the nominal app PLL (24.576MHz) by the data rate. * The relevant equations are from the XU316 datasheet, and are: * * F + 1 + (f+1 / p+1) 1 1 * Fpll2 = Fpll2_in * ------------------- * ------- * -------- * 2 R + 1 OD + 1 - * + * * For given values: * Fpll2_in = 24 (MHz, from oscillator) * F = 408 * R = 3 * OD = 4 * p = 249 - * and expressing Fpll2 as X*s, where X is the nominal frequency and S is the scale applied, we can - * rearrange and simplify to give: + * and expressing Fpll2 as X*s, where X is the nominal frequency and S is the scale applied, we can + * rearrange and simplify to give: * - * [ f + p + 2 ] + * [ f + p + 2 ] * 6 * [ --------- + F ] - * [ f + 1 ] - * ---------------------- + * [ f + 1 ] + * ---------------------- * 5 * (D + 1) * (R + 1) = X*s, substituting in values to give - * * - * [ f + 251 ] + * + * [ f + 251 ] * 6 * [ --------- + 408 ] - * [ 250 ] - * ---------------------- + * [ 250 ] + * ---------------------- * 100 = 24.576 * s, solving for f and simplifying to give - * - * + * + * * f = (102400 * s) - 102251, rounded and converted back to an integer from Q31. */ @@ -75,6 +98,28 @@ bool tud_xcore_data_cb(uint32_t cur_time, uint32_t ep_num, uint32_t ep_dir, size prev_s = s; } +} + +bool tud_xcore_data_cb(uint32_t cur_time, uint32_t ep_num, uint32_t ep_dir, size_t xfer_len) +{ + if (ep_num == USB_AUDIO_EP && + ep_dir == USB_DIR_OUT) + { + if(data_event_queue != NULL) { + BaseType_t xHigherPriorityTaskWoken; + usb_audio_rate_packet_desc_t args; + args.cur_time = cur_time; + args.ep_num = ep_num; + args.ep_dir = ep_dir; + args.xfer_len = xfer_len; + + if( errQUEUE_FULL == + xQueueSendFromISR(data_event_queue, (void *)&args, &xHigherPriorityTaskWoken)) { + rtos_printf("Audio packet timing event dropped\n"); + xassert(0); /* Missed servicing a data packet */ + } + } + } return true; } @@ -88,4 +133,13 @@ bool tud_xcore_sof_cb(uint8_t rhport) void adaptive_rate_adjust_init(chanend_t other_tile_c, xclock_t mclk_clkblk) { + + xTaskCreate((TaskFunction_t) usb_adaptive_clk_manager, + "usb_adpt_mgr", + RTOS_THREAD_STACK_SIZE(usb_adaptive_clk_manager), + NULL, + USB_ADAPTIVE_TASK_PRIORITY, + NULL); + + data_event_queue = xQueueCreate( DATA_EVENT_QUEUE_SIZE, sizeof(usb_audio_rate_packet_desc_t) ); } diff --git a/doc/README.rst b/doc/README.rst index 229e9065..3b0ec100 100644 --- a/doc/README.rst +++ b/doc/README.rst @@ -24,7 +24,7 @@ Pull the docker container: .. code-block:: console - $ docker pull ghcr.io/xmos/doc_builder:main + docker pull ghcr.io/xmos/doc_builder:main ======== Building @@ -34,4 +34,4 @@ To build the documentation, run the following command in the root of the reposit .. code-block:: console - $ docker run --rm -t -u "$(id -u):$(id -g)" -v $(pwd):/build -e REPO:/build -e DOXYGEN_INCLUDE=/build/doc/Doxyfile.inc -e EXCLUDE_PATTERNS=/build/doc/exclude_patterns.inc -e DOXYGEN_INPUT=ignore ghcr.io/xmos/doc_builder:main + docker run --rm -t -u "$(id -u):$(id -g)" -v $(pwd):/build -e REPO:/build -e DOXYGEN_INCLUDE=/build/doc/Doxyfile.inc -e EXCLUDE_PATTERNS=/build/doc/exclude_patterns.inc -e DOXYGEN_INPUT=ignore ghcr.io/xmos/doc_builder:main diff --git a/doc/extending.rst b/doc/extending.rst new file mode 100644 index 00000000..069071de --- /dev/null +++ b/doc/extending.rst @@ -0,0 +1,71 @@ +.. _sln_voice_memory_cpu: + +########################### +Memory and CPU Requirements +########################### + +****** +Memory +****** + +The table below lists the approximate memory requirements for the larger software components. All memory use estimates in the table below are based on the default configuration for the feature. Alternate configurations will require more or less memory. The estimates are provided as guideline to assist application developers judge the memory cost of extending the application or benefit of removing an existing feature. It can be assumed that the memory requirement of components not listed in the table below are under 5 kB. + +.. list-table:: Memory Requirements + :widths: 50 50 + :header-rows: 1 + :align: left + + * - Component + - Memory Use (kB) + * - Stereo Adaptive Echo Canceler (AEC) + - 275 + * - Wanson Speech Recognition Engine + - 194 + * - Interference Canceler (IC) + Voice Activity Detector (VAD) + - 93 + * - USB + - 20 + * - Noise Supressor (NS) + - 15 + * - Adaptive Gain Control (AGC) + - 11 + +*** +CPU +*** + +The table below lists the approximate CPU requirements for the larger software components. All CPU use estimates in the table below are based on the default configuration for the feature. Alternate configurations will require more or less MIPS. The estimates are provided as guideline to assist application developers judge the MIP cost of extending the application or benefits of removing an existing feature. It can be assumed that the memory requirement of components not listed in the table below are under 1%. + +The following formula was used to convert CPU% to MIPS: + +MIPS = (CPU% / 100%) * (600 MHz / 5 cores) + +.. list-table:: CPU Requirements (@ 600 MHz) + :widths: 50 50 50 + :header-rows: 1 + :align: left + + * - Component + - CPU Use (%) + - MIPS Use + * - USB XUD + - 100 + - 120 + * - I2S (slave mode) + - 80 + - 96 + * - Stereo Adaptive Echo Canceler (AEC) + - 80 + - 96 + * - Wanson Speech Recognition Engine + - 80 + - 96 + * - Interference Canceler (IC) + Voice Activity Detector (VAD) + - 20 + - 24 + * - Noise Supressor (NS) + - 10 + - 12 + * - Adaptive Gain Control (AGC) + - 5 + - 6 \ No newline at end of file diff --git a/doc/ffd/modifying_software.rst b/doc/ffd/modifying_software.rst index c6050f28..e1250922 100644 --- a/doc/ffd/modifying_software.rst +++ b/doc/ffd/modifying_software.rst @@ -20,6 +20,8 @@ The FFD reference design consists of three major software blocks, the audio pipe It is highly recommended to be familiar with the application as a whole before attempting replacing these functional units. This information can be found here: :ref:`sln_voice_ffd_software_description` +See :ref:`sln_voice_memory_cpu` for more details on the memory footprint and CPU usage of the major software components. + Replacing XCORE-VOICE DSP Block ------------------------------- diff --git a/doc/stlp/audio_pipeline.rst b/doc/stlp/audio_pipeline.rst index 8c1fb084..e25cf72d 100644 --- a/doc/stlp/audio_pipeline.rst +++ b/doc/stlp/audio_pipeline.rst @@ -1,7 +1,7 @@ -.. _sln_voice_stlp_ap: - .. include:: +.. _sln_voice_stlp_ap: + ############## Audio Pipeline ##############