Skip to content

Commit 40d7392

Browse files
committed
Applications: nrf5340_audio: Improved I2S ISR
OCT-3418 Reduced prints in I2S ISR Make functions inline Reduce overall time spent in ISR Signed-off-by: Kristoffer Skøien <[email protected]>
1 parent 9ba594c commit 40d7392

File tree

1 file changed

+67
-70
lines changed

1 file changed

+67
-70
lines changed

applications/nrf5340_audio/src/audio/audio_datapath.c

Lines changed: 67 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ LOG_MODULE_REGISTER(audio_datapath, CONFIG_AUDIO_DATAPATH_LOG_LEVEL);
8787
#define JUST_IN_TIME_BOUND_US 2500
8888

8989
/* How often to print under-run warning */
90-
#define UNDERRUN_LOG_INTERVAL_BLKS 5000
90+
#define LOG_INTERVAL_BLKS 5000
9191

9292
NET_BUF_POOL_FIXED_DEFINE(pool_i2s_rx, FIFO_NUM_BLKS, BLK_STEREO_SIZE_OCTETS,
9393
sizeof(struct audio_metadata), NULL);
@@ -247,7 +247,7 @@ static void drift_comp_state_set(enum drift_comp_state new_state)
247247
*
248248
* @param frame_start_ts_us I2S frame start timestamp.
249249
*/
250-
static void audio_datapath_drift_compensation(uint32_t frame_start_ts_us)
250+
static inline void audio_datapath_drift_compensation(uint32_t frame_start_ts_us)
251251
{
252252
if (CONFIG_AUDIO_DEV == HEADSET) {
253253
/** For headsets we do not use the timestamp gotten from hci_tx_sync_get to adjust
@@ -580,7 +580,7 @@ static struct {
580580
* @retval 0 if success.
581581
* @retval -ENOMEM No available buffers.
582582
*/
583-
static int alt_buffer_get(void **p_buffer)
583+
static inline int alt_buffer_get(void **p_buffer)
584584
{
585585
if (!alt.buf_0_in_use) {
586586
alt.buf_0_in_use = true;
@@ -601,7 +601,7 @@ static int alt_buffer_get(void **p_buffer)
601601
*
602602
* @param p_buffer Buffer to free.
603603
*/
604-
static void alt_buffer_free(void const *const p_buffer)
604+
static inline void alt_buffer_free(void const *const p_buffer)
605605
{
606606
if (p_buffer == alt.buf_0) {
607607
alt.buf_0_in_use = false;
@@ -619,6 +619,14 @@ static void alt_buffer_free_both(void)
619619
alt.buf_1_in_use = false;
620620
}
621621

622+
static struct audio_metadata i2s_meta = {.data_coding = PCM,
623+
.data_len_us = 1000,
624+
.sample_rate_hz = CONFIG_AUDIO_SAMPLE_RATE_HZ,
625+
.bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS,
626+
.carried_bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS,
627+
.locations = BT_AUDIO_LOCATION_FRONT_LEFT |
628+
BT_AUDIO_LOCATION_FRONT_RIGHT,
629+
.bad_data = false};
622630
/*
623631
* This handler function is called every time I2S needs new buffers for
624632
* TX and RX data.
@@ -632,8 +640,10 @@ static void alt_buffer_free_both(void)
632640
static void audio_datapath_i2s_blk_complete(uint32_t frame_start_ts_us, uint32_t *rx_buf_released,
633641
uint32_t const *tx_buf_released)
634642
{
635-
int ret;
636-
static bool underrun_condition;
643+
int ret = 0;
644+
static uint32_t num_calls;
645+
646+
num_calls++;
637647

638648
alt_buffer_free(tx_buf_released);
639649

@@ -645,83 +655,77 @@ static void audio_datapath_i2s_blk_complete(uint32_t frame_start_ts_us, uint32_t
645655
static uint8_t *tx_buf;
646656

647657
if (IS_ENABLED(CONFIG_STREAM_BIDIRECTIONAL) || (CONFIG_AUDIO_DEV == HEADSET)) {
648-
if (tx_buf_released != NULL) {
649-
/* Double buffered index */
650-
uint32_t next_out_blk_idx = NEXT_IDX(ctrl_blk.out.cons_blk_idx);
651-
652-
if (next_out_blk_idx != ctrl_blk.out.prod_blk_idx) {
653-
/* Only increment if not in under-run condition */
654-
ctrl_blk.out.cons_blk_idx = next_out_blk_idx;
655-
if (underrun_condition) {
656-
underrun_condition = false;
657-
LOG_WRN("Data received, total under-runs: %d",
658-
ctrl_blk.out.total_blk_underruns);
659-
}
658+
static bool underrun_condition;
660659

661-
tx_buf = (uint8_t *)&ctrl_blk.out
662-
.fifo[next_out_blk_idx * BLK_STEREO_NUM_SAMPS];
660+
if (tx_buf_released == NULL) {
661+
ERR_CHK_MSG(-ENOMEM, "No TX data available");
662+
}
663663

664-
} else {
665-
if (stream_state_get() == STATE_STREAMING) {
666-
underrun_condition = true;
667-
ctrl_blk.out.total_blk_underruns++;
664+
/* Double buffered index */
665+
uint32_t next_out_blk_idx = NEXT_IDX(ctrl_blk.out.cons_blk_idx);
668666

669-
if ((ctrl_blk.out.total_blk_underruns %
670-
UNDERRUN_LOG_INTERVAL_BLKS) == 0) {
671-
LOG_WRN("In I2S TX under-run condition, total: %d",
672-
ctrl_blk.out.total_blk_underruns);
673-
}
674-
}
667+
if (next_out_blk_idx != ctrl_blk.out.prod_blk_idx) {
668+
/* Only increment if not in under-run condition */
669+
ctrl_blk.out.cons_blk_idx = next_out_blk_idx;
670+
if (underrun_condition) {
671+
underrun_condition = false;
672+
LOG_WRN("Data received, total under-runs: %d",
673+
ctrl_blk.out.total_blk_underruns);
674+
}
675675

676-
/*
677-
* No data available in out.fifo
678-
* use alternative buffers
679-
*/
680-
ret = alt_buffer_get((void **)&tx_buf);
681-
ERR_CHK(ret);
676+
tx_buf = (uint8_t *)&ctrl_blk.out
677+
.fifo[next_out_blk_idx * BLK_STEREO_NUM_SAMPS];
682678

683-
memset(tx_buf, 0, BLK_STEREO_SIZE_OCTETS);
684-
}
679+
} else {
680+
if (stream_state_get() == STATE_STREAMING) {
681+
underrun_condition = true;
682+
ctrl_blk.out.total_blk_underruns++;
685683

686-
if (tone_active) {
687-
tone_mix(tx_buf);
684+
if ((ctrl_blk.out.total_blk_underruns % LOG_INTERVAL_BLKS) == 0) {
685+
LOG_WRN("In I2S TX under-run condition, total: %d",
686+
ctrl_blk.out.total_blk_underruns);
687+
}
688688
}
689+
690+
/*
691+
* No data available in out.fifo
692+
* use alternative buffers
693+
*/
694+
ret = alt_buffer_get((void **)&tx_buf);
695+
ERR_CHK(ret);
696+
697+
memset(tx_buf, 0, BLK_STEREO_SIZE_OCTETS);
698+
}
699+
700+
if (tone_active) {
701+
tone_mix(tx_buf);
689702
}
690703
}
691704

692705
/********** I2S RX **********/
693-
static int prev_ret;
694706
struct net_buf *rx_audio_block = NULL;
707+
static uint32_t num_overruns;
708+
static uint32_t num_overruns_last_printed;
695709

696710
if (IS_ENABLED(CONFIG_STREAM_BIDIRECTIONAL) || (CONFIG_AUDIO_DEV == GATEWAY)) {
697711
if (rx_buf_released == NULL) {
698-
/* No RX data available */
699712
ERR_CHK_MSG(-ENOMEM, "No RX data available");
700713
}
701714

702715
if (k_msgq_num_free_get(ctrl_blk.in.audio_q) == 0 || pool_i2s_rx.avail_count == 0) {
703-
ret = -ENOMEM;
704-
} else {
705-
ret = 0;
706-
}
707-
708-
/* If RX FIFO is filled up */
709-
if (ret == -ENOMEM) {
716+
/* If RX FIFO is filled up */
717+
num_overruns++;
710718
struct net_buf *stale_i2s_data;
711-
712-
if (ret != prev_ret) {
713-
LOG_WRN("I2S RX overrun. Single msg");
714-
prev_ret = ret;
715-
}
716-
717719
ret = k_msgq_get(ctrl_blk.in.audio_q, (void *)&stale_i2s_data, K_NO_WAIT);
718720
ERR_CHK(ret);
719-
721+
/* Discard data */
720722
net_buf_unref(stale_i2s_data);
723+
}
721724

722-
} else if (ret == 0 && prev_ret == -ENOMEM) {
723-
LOG_WRN("I2S RX continuing stream");
724-
prev_ret = ret;
725+
if ((num_calls % LOG_INTERVAL_BLKS == 0) &&
726+
(num_overruns != num_overruns_last_printed)) {
727+
LOG_WRN("I2S RX overrun count: %d", num_overruns);
728+
num_overruns_last_printed = num_overruns;
725729
}
726730

727731
rx_audio_block = net_buf_alloc(&pool_i2s_rx, K_NO_WAIT);
@@ -732,16 +736,9 @@ static void audio_datapath_i2s_blk_complete(uint32_t frame_start_ts_us, uint32_t
732736
/* Store RX buffer in net_buf */
733737
net_buf_add_mem(rx_audio_block, rx_buf_released, BLK_STEREO_SIZE_OCTETS);
734738

739+
/* Store I2S related metadata */
735740
struct audio_metadata *meta = net_buf_user_data(rx_audio_block);
736-
737-
/* Add meta data */
738-
meta->data_coding = PCM;
739-
meta->data_len_us = 1000;
740-
meta->sample_rate_hz = CONFIG_AUDIO_SAMPLE_RATE_HZ;
741-
meta->bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS;
742-
meta->carried_bits_per_sample = CONFIG_AUDIO_BIT_DEPTH_BITS;
743-
meta->locations = BT_AUDIO_LOCATION_FRONT_LEFT | BT_AUDIO_LOCATION_FRONT_RIGHT;
744-
meta->bad_data = false;
741+
*meta = i2s_meta;
745742

746743
ret = k_msgq_put(ctrl_blk.in.audio_q, (void *)&rx_audio_block, K_NO_WAIT);
747744
ERR_CHK_MSG(ret, "Unable to put RX audio block into queue");
@@ -770,11 +767,11 @@ static void audio_datapath_i2s_start(void)
770767
if (IS_ENABLED(CONFIG_STREAM_BIDIRECTIONAL) || (CONFIG_AUDIO_DEV == HEADSET)) {
771768
ctrl_blk.out.cons_blk_idx = PREV_IDX(ctrl_blk.out.cons_blk_idx);
772769
tx_buf_0 = (uint8_t *)&ctrl_blk.out
773-
.fifo[ctrl_blk.out.cons_blk_idx * BLK_STEREO_NUM_SAMPS];
770+
.fifo[ctrl_blk.out.cons_blk_idx * BLK_STEREO_NUM_SAMPS];
774771

775772
ctrl_blk.out.cons_blk_idx = PREV_IDX(ctrl_blk.out.cons_blk_idx);
776773
tx_buf_1 = (uint8_t *)&ctrl_blk.out
777-
.fifo[ctrl_blk.out.cons_blk_idx * BLK_STEREO_NUM_SAMPS];
774+
.fifo[ctrl_blk.out.cons_blk_idx * BLK_STEREO_NUM_SAMPS];
778775
}
779776

780777
/* Start I2S */

0 commit comments

Comments
 (0)