diff --git a/arch/arm/src/lc823450/lc823450_i2s.c b/arch/arm/src/lc823450/lc823450_i2s.c index e04bf4f6712..12810f08e15 100644 --- a/arch/arm/src/lc823450/lc823450_i2s.c +++ b/arch/arm/src/lc823450/lc823450_i2s.c @@ -319,9 +319,9 @@ static void _setup_audio_pll(uint32_t freq) * Name: _i2s_semtake ****************************************************************************/ -static void _i2s_semtake(FAR sem_t *sem) +static int _i2s_semtake(FAR sem_t *sem) { - nxsem_wait_uninterruptible(sem); + return nxsem_wait_uninterruptible(sem); } /**************************************************************************** @@ -500,6 +500,8 @@ static int lc823450_i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, i2s_callback_t callback, void *arg, uint32_t timeout) { + int ret = OK; + #if 1 /* TODO: should move to rxsamplerate later */ if (false == _b_input_started) { @@ -522,7 +524,19 @@ static int lc823450_i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, /* Wait for Audio Buffer */ - _i2s_semtake(&_sem_buf_over); + ret = _i2s_semtake(&_sem_buf_over); + if (ret < 0) + { + /* Disable J Buffer Over Level IRQ */ + + modifyreg32(ABUFIRQEN0, ABUFIRQEN0_BOLIRQEN('J'), 0); + + /* Stop J Buffer */ + + modifyreg32(ABUFACCEN, ABUFACCEN_CDCEN('J'), 0); + + return ret; + } volatile uint32_t *ptr = (uint32_t *)&apb->samp[apb->curbyte]; uint32_t n = apb->nmaxbytes; @@ -539,7 +553,15 @@ static int lc823450_i2s_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb, _i2s_rxdma_callback, &_sem_rxdma); - _i2s_semtake(&_sem_rxdma); + ret = _i2s_semtake(&_sem_rxdma); + if (ret < 0) + { + /* Stop DMA because semtake failed */ + + lc823450_dmastop(_hrxdma); + + return ret; + } /* Invoke the callback handler */ @@ -643,6 +665,7 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, uint32_t n = apb->nbytes; uint32_t bufc_enabled; uint32_t decsel; + int ret = OK; DEBUGASSERT(0 < n); @@ -665,7 +688,15 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, /* Wait for Audio Buffer */ - _i2s_semtake(&_sem_buf_under); + ret = _i2s_semtake(&_sem_buf_under); + if (ret < 0) + { + /* Disable C Buffer Under Level IRQ */ + + modifyreg32(ABUFIRQEN0, ABUFIRQEN0_BULIRQEN('C'), 0); + + return ret; + } } if (0 == decsel && (n & 0x3)) @@ -705,7 +736,15 @@ static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb, _i2s_txdma_callback, &_sem_txdma); - _i2s_semtake(&_sem_txdma); + ret = _i2s_semtake(&_sem_txdma); + if (ret < 0) + { + /* Stop DMA because semtake failed */ + + lc823450_dmastop(_htxdma); + + return ret; + } #ifdef SHOW_BUFFERING if (0 == bufc_enabled)