//This routine is called as soon as the DMA routine has something to tell us. All we //handle here is the RX_EOF_INT status, which indicate the DMA has sent a buffer whose //descriptor has the 'EOF' field set to 1. LOCAL void slc_isr(void) { portBASE_TYPE HPTaskAwoken=0; struct sdio_queue *finishedDesc; uint32 slc_intr_status; int dummy; //Grab int status slc_intr_status = READ_PERI_REG(SLC_INT_STATUS); //clear all intr flags WRITE_PERI_REG(SLC_INT_CLR, slc_intr_status); // 0xffffffff); if (slc_intr_status & SLC_RX_EOF_INT_ST) { //The DMA subsystem is done with this block: Push it on the queue so it can be re-used. finishedDesc=(struct sdio_queue*)READ_PERI_REG(SLC_RX_EOF_DES_ADDR); if (xQueueIsQueueFullFromISR(dmaQueue)) { //All buffers are empty. This means we have an underflow on our hands. underrunCnt++; //Pop the top off the queue; it's invalid now anyway. xQueueReceiveFromISR(dmaQueue, &dummy, &HPTaskAwoken); } //Dump the buffer on the queue so the rest of the software can fill it. xQueueSendFromISR(dmaQueue, (void*)(&finishedDesc->buf_ptr), &HPTaskAwoken); } //We're done. portEND_SWITCHING_ISR(HPTaskAwoken); }
wiced_result_t wiced_rtos_is_queue_full( wiced_queue_t* queue ) { signed portBASE_TYPE result; taskENTER_CRITICAL(); result = xQueueIsQueueFullFromISR( *queue ); taskEXIT_CRITICAL(); return ( result != 0 ) ? WICED_SUCCESS : WICED_ERROR; }
// DMA interrupt handler. It is called each time a DMA block is finished processing. static void dma_isr_handler(void) { portBASE_TYPE task_awoken = pdFALSE; if (i2s_dma_is_eof_interrupt()) { dma_descriptor_t *descr = i2s_dma_get_eof_descriptor(); if (xQueueIsQueueFullFromISR(dma_queue)) { // List of empty blocks is full. Sender don't send data fast enough. int dummy; underrun_counter++; // Discard top of the queue xQueueReceiveFromISR(dma_queue, &dummy, &task_awoken); } // Push the processed buffer to the queue so sender can refill it. xQueueSendFromISR(dma_queue, (void*)(&descr->buf_ptr), &task_awoken); } i2s_dma_clear_interrupt(); portEND_SWITCHING_ISR(task_awoken); }
/** Audio ISR (FIFO) * * * Parameters: * @param pThisArg Initialized Audio (TX/RX) object * * @return None */ void audioRxTx_isr(void *pThisArg) { audioRxTx_t *pThis = (audioRxTx_t*) pThisArg; chunk_d_t *pChunk = NULL; unsigned int samplesInChunk; /* Read FIFO Interrupt Status */ unsigned int intStatus = *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_INT_STATUS); /* Tx FIFO programmable empty hit */ if (intStatus & FIFO_INT_TFPE) { /* clear TFPE interrupt */ *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_INT_STATUS) = FIFO_INT_TFPE; /* Check if Tx queue is EMPTY * - set signal that ISR is not running * - return */ if (xQueueIsQueueEmptyFromISR(pThis->tx_queue) != pdFALSE) { pThis->running = 0; /* indicate that ISR is no longer running */ return; } // Tx Queue is not empty - Receive pointer to the next chunk. xQueueReceiveFromISR(pThis->tx_queue, &pChunk, NULL); /* how many samples does the chunk contain ? */ samplesInChunk = pChunk->bytesUsed/sizeof(unsigned int); // This check might not really be needed - as we have recieved a TPFE trigger from FIFO if (samplesInChunk > (*(volatile u32 *) (FIFO_BASE_ADDR + FIFO_TX_VAC))) { printf("audioTx_isr: insufficient space in FIFO\n"); // should anyway never happen // if TX FIFO Does not have the space promised, just drop the chunk bufferPool_d_release_from_ISR(pThis->pBuffP, pChunk); return; } /* Transmit the chunk data to the TX FIFO */ u32 samplNr = 0; for (samplNr = 0; samplNr < samplesInChunk; samplNr++) { *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_TX_DATA) = ((unsigned int)pChunk->u16_buff[samplNr]) << 16; *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_TX_LENGTH) = 0x1; } /* Return chunk to buffer pool free list */ bufferPool_d_release_from_ISR(pThis->pBuffP, pChunk); } /* RX FIFO programmable Full hit */ if (intStatus & FIFO_INT_RFPF) { /* Clear RFPF interrupt */ *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_INT_STATUS) = FIFO_INT_RFPF; /* is Queue is full ? */ if ((xQueueIsQueueFullFromISR(pThis->rx_queue)) != pdFALSE) { printf( "The RX queue is full, and no more incoming data could be captured\n"); *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_INT_ENABLE) = 0x0; return; } while (bufferPool_d_acquire_ISR(pThis->pBuffP, &pChunk) != 1) { printf("RX ISR: buffer pool empty\n\n\n\n\n"); *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_INT_ENABLE) = 0x0; return; } // How many samples in FIFO? samplesInChunk = *(volatile u32 *) (FIFO_BASE_ADDR + FIFO_RX_OCC); // more samples in FIFO than fitting into chunk? Limit if(samplesInChunk > pChunk->bytesMax/4){ samplesInChunk = pChunk->bytesMax/4; } /* Read the Audio RX samples.*/ u32 samplNr = 0; for (samplNr = 0; samplNr < samplesInChunk; samplNr++) { // read from FIFO and right shift by 16 (8 LSBs are 0 anyway, plus we want to use 16 bit only). // symmetric to tx side. pChunk->u16_buff[samplNr] = (unsigned short) ((*(volatile u32 *) (FIFO_BASE_ADDR + FIFO_RX_DATA)) >> 16); } /* indicate max fill level */ pChunk->bytesUsed= samplesInChunk * 4; xQueueSendFromISR( pThis->rx_queue, &pChunk, NULL); return; }