//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);
}
Example #2
0
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);
}
Example #4
0
/** 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;

	}