From c46741975dacc334ea2394c2cf3d6b994e88da1b Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Mon, 6 Aug 2018 03:39:45 +0000 Subject: [PATCH] Merged in masayuki2009/nuttx.nuttx/fix_http_streaming_with_lc823450 (pull request #705) Fix http streaming with lc823450 * arch/arm/src/lc823450: Change C-Buffer under-level control The under-level setting was changed from 1KB to 55KB. In previous implementation, the setting can ben changed by the tx threshold but it is fixed at startup. Also, check write size and adjust alignment if needed. Signed-off-by: Masayuki Ishikawa * configs/lc823450-xgevk: Change IOB related params for rndis. Since TCP flow control scheme was changed, HTTP audio streaming has not been working. These IOB params are not optimized but HTTP audio streaming now works. Signed-off-by: Masayuki Ishikawa Approved-by: GregoryN --- arch/arm/src/lc823450/lc823450_i2s.c | 56 ++++++++++++++++++-------- configs/lc823450-xgevk/rndis/defconfig | 6 +-- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/arch/arm/src/lc823450/lc823450_i2s.c b/arch/arm/src/lc823450/lc823450_i2s.c index 080bf7b82e9..2eed848def7 100644 --- a/arch/arm/src/lc823450/lc823450_i2s.c +++ b/arch/arm/src/lc823450/lc823450_i2s.c @@ -404,7 +404,7 @@ static void lc823450_i2s_setchannel(char id, uint8_t ch) } /**************************************************************************** - * Name: _setup_tx_threshold + * Name: _setup_tx_threshold (threshold to start playback) ****************************************************************************/ static void _setup_tx_threshold(uint32_t tx_th) @@ -422,7 +422,7 @@ static void _setup_tx_threshold(uint32_t tx_th) _i2s_tx_th_bytes = getreg32(BUF_SIZE('C')) * tx_th / 100; } - putreg32(_i2s_tx_th_bytes, BUF_ULVL('C')); + /* NOTE: Buffer Under Level is not controlled by tx threshold */ } /**************************************************************************** @@ -660,6 +660,12 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, { volatile uint32_t *ptr = (uint32_t *)&apb->samp[apb->curbyte]; uint32_t n = apb->nbytes; + uint32_t bufc_enabled; + uint32_t decsel; + + ASSERT(0 < n); + + decsel = getreg32(AUDSEL) & AUDSEL_DECSEL; if (0 == getreg32(BUF_DTCAP('C'))) { @@ -668,7 +674,9 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, modifyreg32(ABUFACCEN, ABUFACCEN_CDCEN('C'), 0); } - if (getreg32(ABUFACCEN) & ABUFACCEN_CDCEN('C')) + bufc_enabled = getreg32(ABUFACCEN) & ABUFACCEN_CDCEN('C'); + + if (bufc_enabled) { /* Enable C Buffer Under Level IRQ */ @@ -679,17 +687,23 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, _i2s_semtake(&_sem_buf_under); } + if (0 == decsel && (n & 0x3)) + { + auderr("** PCM data is not word-aligned (n=%d) ** \n", n); + + /* Set size to align on a word boundary */ + + n &= ~0x3; + + if (0 == n) + { + goto out; + } + } + /* Setup and start DMA for I2S */ - if (0 == (n % 4)) - { - lc823450_dmasetup(_htxdma, - LC823450_DMA_SRCINC | - LC823450_DMA_SRCWIDTH_WORD | - LC823450_DMA_DSTWIDTH_WORD, - (uint32_t)ptr, (uint32_t)BUF_ACCESS('C'), n / 4); - } - else + if (n & 0x3) { lc823450_dmasetup(_htxdma, LC823450_DMA_SRCINC | @@ -697,6 +711,14 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, LC823450_DMA_DSTWIDTH_BYTE, (uint32_t)ptr, (uint32_t)BUF_ACCESS('C'), n); } + else + { + lc823450_dmasetup(_htxdma, + LC823450_DMA_SRCINC | + LC823450_DMA_SRCWIDTH_WORD | + LC823450_DMA_DSTWIDTH_WORD, + (uint32_t)ptr, (uint32_t)BUF_ACCESS('C'), n / 4); + } lc823450_dmastart(_htxdma, _i2s_txdma_callback, @@ -705,7 +727,7 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, _i2s_semtake(&_sem_txdma); #ifdef SHOW_BUFFERING - if (0 == (getreg32(ABUFACCEN) & ABUFACCEN_CDCEN('C'))) + if (0 == bufc_enabled) { audinfo("buffering (remain=%d) \n", getreg32(BUF_DTCAP('C'))); } @@ -713,11 +735,13 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, /* Start C Buffer */ - if (_i2s_tx_th_bytes < getreg32(BUF_DTCAP('C'))) + if (0 == bufc_enabled && _i2s_tx_th_bytes < getreg32(BUF_DTCAP('C'))) { modifyreg32(ABUFACCEN, 0, ABUFACCEN_CDCEN('C')); } +out: + /* Invoke the callback handler */ callback(dev, apb, arg, 0); @@ -861,12 +885,12 @@ static int lc823450_i2s_configure(void) putreg32(MCLKCNTEXT3_AUDIOBUF_CLKEN, MCLKCNTEXT3); - /* C Buffer : size=56KB, under level=1kB */ + /* C Buffer : size=56KB, under level=55kB */ putreg32(base, BUF_BASE('C')); putreg32(1024 * 56, BUF_SIZE('C')); base += 1024 * 56; - putreg32(1024, BUF_ULVL('C')); + putreg32(1024 * 55, BUF_ULVL('C')); /* Setup F Buffer : size=512B */ diff --git a/configs/lc823450-xgevk/rndis/defconfig b/configs/lc823450-xgevk/rndis/defconfig index eabe262e9ed..91c64f82c5a 100644 --- a/configs/lc823450-xgevk/rndis/defconfig +++ b/configs/lc823450-xgevk/rndis/defconfig @@ -57,9 +57,9 @@ CONFIG_I2CTOOL_MAXBUS=1 CONFIG_I2C_RESET=y CONFIG_I2S=y CONFIG_INTELHEX_BINARY=y -CONFIG_IOB_BUFSIZE=384 -CONFIG_IOB_NBUFFERS=128 -CONFIG_IOB_NCHAINS=64 +CONFIG_IOB_BUFSIZE=128 +CONFIG_IOB_NBUFFERS=64 +CONFIG_IOB_NCHAINS=10 CONFIG_LC823450_I2C0=y CONFIG_LC823450_I2C1=y CONFIG_LC823450_I2S0=y