Exemple #1
0
/*FUNCTION**********************************************************************
*
* Function Name : SND_RxCallback
* Description	: Callback function to tell that audio controller have finished
*  a period data.
* The function would update the buffer status information.
*END**************************************************************************/
void SND_RxCallback(void *param)
{
    sound_card_t *card = (sound_card_t *)param;
    audio_buffer_t *buffer = &card->buffer;
    buffer->queued += buffer->size;
    /* Change the current buffer. */
    if (buffer->input_index == buffer->blocks - 1)
    {  
        buffer->input_curbuff = buffer->buff;
        buffer->input_index = 0;
    }
    else
    {
        buffer->input_index ++;
        buffer->input_curbuff += buffer->size;
    }
    buffer->empty_block -= 1;
    buffer->full_block += 1;
    /* Judge if need to close the SAI transfer, while the buffer is full, 
     * we need to close the SAI */
    if (buffer->input_index == buffer->output_index)
    {
        SND_RxStop(card);
        buffer->buffer_error ++;
        buffer->first_io = true;
    }
#if !USEDMA
    audio_controller_t *ctrl = &card->controller;
    ctrl->ops->Ctrl_ReceiveData(ctrl->instance, buffer->input_curbuff, buffer->size);
#endif
    OSA_SemaPost(&buffer->sem);
}
/*!
 * @brief Finish up a transfer.
 * Cleans up after a transfer is complete. Interrupts are disabled, and the SPI module
 * is disabled. This is not a public API as it is called from other driver functions.
 */
static void SPI_DRV_MasterCompleteTransfer(uint32_t instance)
{
    /* instantiate local variable of type spi_master_state_t and point to global state */
    spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance];

    SPI_Type *base = g_spiBase[instance];

    /* The transfer is complete.*/
    spiState->isTransferInProgress = false;

    /* Disable interrupts */
    SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, false);
    SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false);

#if FSL_FEATURE_SPI_16BIT_TRANSFERS
    if (g_spiFifoSize[instance] != 0)
    {
        /* Now disable the SPI FIFO interrupts */
        SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, false);
        SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false);
    }
#endif

    if (spiState->isTransferBlocking)
    {
        /* Signal the synchronous completion object */
        OSA_SemaPost(&spiState->irqSync);
    }
}
Exemple #3
0
void stop_edma_loop(void *parameter, edma_chn_status_t status)
{
    /* Increase semaphore to indicate an eDMA channel has completed transfer. */
    OSA_SemaPost(&g_statusSem);

    /* Stop eDMA channel transfers. */
    EDMA_DRV_StopChannel((edma_chn_state_t *)parameter);
}
/*!
 * @brief Interrupt handler for TSI.
 * This handler uses the tsi State structure to handle the instance depend data.
 * This is not a public API as it is called whenever an interrupt occurs.
 */
void TSI_DRV_IRQHandler(uint32_t instance)
{
    TSI_Type * base = g_tsiBase[instance];
    tsi_state_t * tsiState = g_tsiStatePtr[instance];
    uint32_t channels = tsiState->opModesData[tsiState->opMode].enabledElectrodes;
    uint32_t curr_channel = TSI_HAL_GetMeasuredChannelNumber(base);
    uint32_t next_pen, pen;
    /* Check if a measure is running and wanted. */

    TSI_HAL_ClearOutOfRangeFlag(base);
    TSI_HAL_ClearEndOfScanFlag(base);

    if((uint32_t)(1 << curr_channel) & channels)
    {
        /* Am I in noise mode? */
        if(tsiState->opMode == tsi_OpModeNoise)
        {
            tsiState->counters[curr_channel] = TSI_HAL_GetMode(base);
        }
        else
        {
            tsiState->counters[curr_channel] = TSI_HAL_GetCounter(base);
        }
    }
    
    next_pen = curr_channel + 1;
    pen = channels;
    while (((((pen >> next_pen) & 0x1U)) == 0U) && (next_pen < 16)) 
    {
        next_pen++;
    }
    
    if(next_pen < 16)
    {
        /* Measurement must continue on next channel. */
        TSI_HAL_SetMeasuredChannelNumber(base, next_pen);
        TSI_HAL_StartSoftwareTrigger(base);
        return;
    }
    
    if(tsiState->isBlockingMeasure)
    {
        /* Signal the synchronous completion object. */
        OSA_SemaPost(&tsiState->irqSync);
        tsiState->isBlockingMeasure = false;
    }
    else if(tsiState->pCallBackFunc)
    {
        tsiState->pCallBackFunc(instance, tsiState->usrData);
    }

    if(tsiState->status != kStatus_TSI_LowPower)
    {
        /* Return status of the driver to initialized state */
        tsiState->status = kStatus_TSI_Initialized;
    }
}
Exemple #5
0
/**
 * fill the semaphore for wake-up sources to take
 * @return status flag
 */
power_status_t power_PostToSTSema()
{
	osa_status_t
		status = OSA_SemaPost( &power_STSema );

	if ( kStatus_OSA_Success == status )
	{
		return POWER_STATUS_SUCCESS;
	}
	else
	{
		return POWER_STATUS_ERROR;
	}
}
Exemple #6
0
static int nio_dummy_write(void *dev_context, void *fp_context, const void *buf, size_t nbytes, int *error) {
    NIO_DUMMY_DEV_CONTEXT_STRUCT *devc = (NIO_DUMMY_DEV_CONTEXT_STRUCT*)dev_context;
    NIO_DUMMY_FP_CONTEXT_STRUCT *fpc = (NIO_DUMMY_FP_CONTEXT_STRUCT*)fp_context;

    fpc->wcnt += nbytes;
    OSA_SemaWait(&devc->lock, OSA_WAIT_FOREVER);
    devc->total += nbytes;
    devc->wtotal += nbytes;
    OSA_SemaPost(&devc->lock);

    /* todo: replace with OSA yield. Not part of OSA yet */
    OSA_TimeDelay(1);

    return 0;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : LPSCI_DRV_DmaCompleteReceiveData
 * Description   : Finish up a receive by completing the process of receiving data
 * and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void LPSCI_DRV_DmaCompleteReceiveData(uint32_t instance)
{
    assert(instance < UART0_INSTANCE_COUNT);

    lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance];

    /* Stop DMA channel. */
    DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciRx);

    /* Signal the synchronous completion object. */
    if (lpsciDmaState->isRxBlocking)
    {
        OSA_SemaPost(&lpsciDmaState->rxIrqSync);
    }

    /* Update the information of the module driver state */
    lpsciDmaState->isRxBusy = false;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : LPUART_DRV_DmaCompleteSendData
 * Description   : Finish up a transmit by completing the process of sending
 * data and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void LPUART_DRV_DmaCompleteSendData(uint32_t instance)
{
    assert(instance < LPUART_INSTANCE_COUNT);

    lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance];

    /* Stop DMA channel. */
    DMA_DRV_StopChannel(&lpuartDmaState->dmaLpuartTx);

    /* Signal the synchronous completion object. */
    if (lpuartDmaState->isTxBlocking)
    {
        OSA_SemaPost(&lpuartDmaState->txIrqSync);
    }

    /* Update the information of the module driver state */
    lpuartDmaState->isTxBusy = false;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : UART_DRV_DmaCompleteReceiveData
 * Description   : Finish up a receive by completing the process of receiving data
 * and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void UART_DRV_DmaCompleteReceiveData(uint32_t instance)
{
    assert(instance < UART_INSTANCE_COUNT);

    uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance];

    /* Stop DMA channel. */
    DMA_DRV_StopChannel(&uartDmaState->dmaUartRx);

    /* Signal the synchronous completion object. */
    if (uartDmaState->isRxBlocking)
    {
        OSA_SemaPost(&uartDmaState->rxIrqSync);
    }

    /* Update the information of the module driver state */
    uartDmaState->isRxBusy = false;
}
Exemple #10
0
/*FUNCTION**********************************************************************
 *
 * Function Name : LPSCI_DRV_CompleteReceiveData
 * Description   : Finish up a receive by completing the process of receiving data
 * and disabling the interrupt. 
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void LPSCI_DRV_CompleteReceiveData(uint32_t instance)
{
    assert(instance < HW_UART0_INSTANCE_COUNT);

    lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance];
    uint32_t baseAddr = g_lpsciBaseAddr[instance];

    /* Disable receive data full interrupt */
    LPSCI_HAL_SetRxDataRegFullIntCmd(baseAddr, false);

    /* Signal the synchronous completion object. */
    if (lpsciState->isRxBlocking)
    {
        OSA_SemaPost(&lpsciState->rxIrqSync);
    }

    /* Update the information of the module driver state */
    lpsciState->isRxBusy = false;
}
Exemple #11
0
/*FUNCTION**********************************************************************
 *
 * Function Name : LPSCI_DRV_CompleteSendData
 * Description   : Finish up a transmit by completing the process of sending 
 * data and disabling the interrupt. 
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void LPSCI_DRV_CompleteSendData(uint32_t instance)
{
    assert(instance < HW_UART0_INSTANCE_COUNT);

    uint32_t baseAddr = g_lpsciBaseAddr[instance];
    lpsci_state_t * lpsciState = (lpsci_state_t *)g_lpsciStatePtr[instance];

    /* Disable the transmitter data register empty interrupt */
    LPSCI_HAL_SetTxDataRegEmptyIntCmd(baseAddr, false);

    /* Signal the synchronous completion object. */
    if (lpsciState->isTxBlocking)
    {
        OSA_SemaPost(&lpsciState->txIrqSync);
    }

    /* Update the information of the module driver state */
    lpsciState->isTxBusy = false; 
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MsgQPut
 * Description   : This function is used to put a message to a message queue.
 * Return kStatus_OSA_Success if the message is put successfully, otherwise
 * return kStatus_OSA_Error.
 *
 *END**************************************************************************/
osa_status_t OSA_MsgQPut(msg_queue_handler_t handler, void* pMessage)
{
    assert(handler);
    uint32_t *from_ptr, *to_ptr;
    uint16_t msgSize;

    /* Check that there is room in the queue */
    INT_SYS_DisableIRQGlobal();
    if((handler->tail != handler->head) || (handler->isEmpty))
    {
        from_ptr = (uint32_t*)pMessage;
        to_ptr   = &handler->queueMem[handler->tail * handler->size];

        /* Copy entire message into the queue, based on the size configured at creation */
        msgSize = handler->size;
        while(msgSize--)
        {
            *to_ptr++ = *from_ptr++;
        }

        /* Adjust tail pointer and wrap in case the end of the buffer is reached */
        ++handler->tail;
        if(handler->tail == handler->number)
        {
            handler->tail = 0;
        }

        /* If queue was empty, clear the empty flag and signal that it is not empty anymore */
        if(handler->isEmpty)
        {
            handler->isEmpty = false;
            OSA_SemaPost(&handler->queueSem);
        }
        INT_SYS_EnableIRQGlobal();

        return kStatus_OSA_Success;
    }
    else
    {
        INT_SYS_EnableIRQGlobal();
        return kStatus_OSA_Error;
    }
}
/*FUNCTION**********************************************************************
 *
 * Function Name : LPUART_DRV_CompleteSendData
 * Description   : Finish up a transmit by completing the process of sending
 * data and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void LPUART_DRV_CompleteSendData(uint32_t instance)
{
    assert(instance < LPUART_INSTANCE_COUNT);

    LPUART_Type * base = g_lpuartBase[instance];
    lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance];

    /* Disable transmission complete interrupt */
    LPUART_BWR_CTRL_TIE(base, 0U);

    /* Signal the synchronous completion object. */
    if (lpuartState->isTxBlocking)
    {
        OSA_SemaPost(&lpuartState->txIrqSync);
    }

    /* Update the information of the module driver state */
    lpuartState->isTxBusy = false;
}
/*!
 * @brief Interrupt handler for TSI.
 * This handler uses the tsi State structure to handle the instance depend data.
 * This is not a public API as it is called whenever an interrupt occurs.
 */
void TSI_DRV_IRQHandler(uint32_t instance)
{
    TSI_Type * base = g_tsiBase[instance];
    uint32_t channels = TSI_HAL_GetEnabledChannels(base);
    uint32_t i;
    tsi_state_t * tsiState = g_tsiStatePtr[instance];
    /* Check if a measure is running and wanted. */

    if(tsiState->status != kStatus_TSI_Busy)
    {
        return;
    }

    TSI_HAL_ClearOutOfRangeFlag(base);
    TSI_HAL_ClearEndOfScanFlag(base);

    for(i = 0; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++)
    {
        if((uint32_t)(1 << i) & channels)
        {
            tsiState->counters[i] = TSI_HAL_GetCounter(base, i);
        }
    }


    if(tsiState->isBlockingMeasure)
    {
        /* Signal the synchronous completion object. */
        OSA_SemaPost(&tsiState->irqSync);
        tsiState->isBlockingMeasure = false;
    }
    else if(tsiState->pCallBackFunc)
    {
        tsiState->pCallBackFunc(instance, tsiState->usrData);
    }

    if(tsiState->status != kStatus_TSI_LowPower)
    {
        /* Return status of the driver to initialized state */
        tsiState->status = kStatus_TSI_Initialized;
    }
}
Exemple #15
0
/*FUNCTION**********************************************************************
*
* Function Name : SND_TxCallback
* Description	: Callback function to tell that audio controller have finished 
* a period data.
* The function would update the buffer status information.
*END**************************************************************************/
void SND_TxCallback(void *param)
{
    sound_card_t *card = (sound_card_t *)param;
    audio_buffer_t *buffer = &card->buffer;
    if(buffer->queued == 0)
    {
        return;
    }
    buffer->processed += buffer->size;
    buffer->queued -= buffer->size;

    /* Change the current buffer */
    if (buffer->output_index == buffer->blocks - 1)
    {
        buffer->output_curbuff = buffer->buff;
        buffer->output_index = 0;
    }
    else
    {
        buffer->output_index ++;
        buffer->output_curbuff += buffer->size;
    }
    /* Update the status */
    buffer->empty_block += 1;
    buffer->full_block -= 1;
    /* Judge if need to close the SAI transfer. */
    if (buffer->input_index == buffer->output_index)
    {
        SND_TxStop(card);
        buffer->buffer_error ++;
        buffer->first_io = true;
    }
    else
    {
#if !USEDMA
    audio_controller_t * ctrl = &card->controller;
    ctrl->ops->Ctrl_SendData(ctrl->instance, buffer->output_curbuff, buffer->size);
#endif
    }
    /* post the sync */
    OSA_SemaPost(&buffer->sem);
}
Exemple #16
0
void UART_DRV_CompleteSendData(uint32_t instance)
{
   // assert(instance < HW_UART_UART_APP_INDEX_COUNT);
    mico_uart_t uart = getUartBy(instance);

    uint32_t baseAddr = g_uartBaseAddr[instance];
    uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance];
    /* Disable the transmitter data register empty interrupt */
    UART_HAL_SetTxDataRegEmptyIntCmd(baseAddr, false);

    /* Signal the synchronous completion object. */
    if (uartState->isTxBlocking)
    {
        OSA_SemaPost(&uartState->txIrqSync);
        mico_rtos_set_semaphore(&uart_interfaces[uart].tx_complete);
    }

    /* Update the information of the module driver state */
    uartState->isTxBusy = false; 
}
/*FUNCTION**********************************************************************
 *
 * Function Name : LPUART_DRV_CompleteReceiveData
 * Description   : Finish up a receive by completing the process of receiving data
 * and disabling the interrupt.
 * This is not a public API as it is called from other driver functions.
 *
 *END**************************************************************************/
static void LPUART_DRV_CompleteReceiveData(uint32_t instance)
{
    assert(instance < LPUART_INSTANCE_COUNT);

    lpuart_state_t * lpuartState = (lpuart_state_t *)g_lpuartStatePtr[instance];
    LPUART_Type * base = g_lpuartBase[instance];

    /* disable receive data full and rx overrun interrupt. */
    LPUART_BWR_CTRL_RIE(base, 0U);
    LPUART_HAL_SetIntMode(base, kLpuartIntRxOverrun, false);

    /* Signal the synchronous completion object. */
    if (lpuartState->isRxBlocking)
    {
        OSA_SemaPost(&lpuartState->rxIrqSync);
    }

    /* Update the information of the module driver state */
    lpuartState->isRxBusy = false;
}
/*!
 * @brief Finish up a transfer.
 * Cleans up after a transfer is complete. Interrupts are disabled, and the DSPI module
 * is disabled. This is not a public API as it is called from other driver functions.
 */
static void DSPI_DRV_DmaMasterCompleteTransfer(uint32_t instance)
{
    /* instantiate local variable of type dspi_dma_master_state_t and point to global state */
    dspi_dma_master_state_t * dspiDmaState = (dspi_dma_master_state_t *)g_dspiStatePtr[instance];
    SPI_Type *base = g_dspiBase[instance];

    /* The transfer is complete.*/
    dspiDmaState->isTransferInProgress = false;

    /* Disable the Receive FIFO Drain DMA Request */
    DSPI_HAL_SetRxFifoDrainDmaIntMode(base, kDspiGenerateDmaReq, false);

    /* Disable TFFF DMA request */
    DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false);

    if (dspiDmaState->isTransferBlocking)
    {
        /* Signal the synchronous completion object */
        OSA_SemaPost(&dspiDmaState->irqSync);
    }
}
/*!
 * @brief Finish up a transfer.
 * Cleans up after a transfer is complete. Interrupts are disabled, and the SPI module
 * is disabled. This is not a public API as it is called from other driver functions.
 */
static void SPI_DRV_DmaMasterCompleteTransfer(uint32_t instance)
{
    /* instantiate local variable of type spi_dma_master_state_t and point to global state */
    spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance];

    SPI_Type *base = g_spiBase[instance];

    /* Disable DMA requests and interrupts. */
    SPI_HAL_SetRxDmaCmd(base, false);
    SPI_HAL_SetTxDmaCmd(base, false);
    SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false);

    /* The transfer is complete.*/
    spiDmaState->isTransferInProgress = false;

    if (spiDmaState->isTransferBlocking)
    {
        /* Signal the synchronous completion object */
        OSA_SemaPost(&spiDmaState->irqSync);
    }
}
/*FUNCTION**********************************************************************
*
* Function Name : TSI_DRV_AbortMeasure
* Description   : This function aborts possible measure cycle.
*
*END**************************************************************************/
tsi_status_t TSI_DRV_AbortMeasure(uint32_t instance)
{
    assert(instance < TSI_INSTANCE_COUNT);

    TSI_Type * base = g_tsiBase[instance];
    tsi_status_t  status = kStatus_TSI_Success;
    tsi_state_t * tsiState = g_tsiStatePtr[instance];

    /* Critical section. Access to global variable */
    if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER))
    {
        return kStatus_TSI_Error;
    }

    if(tsiState->status == kStatus_TSI_Recalibration)
    {
       status = kStatus_TSI_Recalibration;
    }
    else if(tsiState->status != kStatus_TSI_Initialized)
    {
        TSI_HAL_ClearOutOfRangeFlag(base);
        TSI_HAL_ClearEndOfScanFlag(base);
        TSI_HAL_DisableModule(base);

        if(tsiState->isBlockingMeasure)
        {
            /* Signal the synchronous completion object. */
            OSA_SemaPost(&tsiState->irqSync);
            tsiState->isBlockingMeasure = false;
        }

        /* Return status of the driver to initialized state */
        tsiState->status = kStatus_TSI_Initialized;
    }

    /* End of critical section. */
    OSA_MutexUnlock(&tsiState->lock);

    return status;
}
/*!
 * @brief Initiate (start) a transfer using DMA. This is not a public API as it is called from
 *  other driver functions
 */
spi_status_t SPI_DRV_DmaMasterStartTransfer(uint32_t instance,
                                            const spi_dma_master_user_config_t * device)
{
    /* instantiate local variable of type spi_dma_master_state_t and point to global state */
    spi_dma_master_state_t * spiDmaState = (spi_dma_master_state_t *)g_spiStatePtr[instance];

    /* For temporarily storing DMA register channel */
    void * param;
    uint32_t calculatedBaudRate;
    SPI_Type *base = g_spiBase[instance];
    uint32_t transferSizeInBytes;  /* DMA transfer size in bytes */

    /* Initialize s_byteToSend */
    s_byteToSend = 0;

    /* If the transfer count is zero, then return immediately.*/
    if (spiDmaState->remainingSendByteCount == 0)
    {
        /* Signal the synchronous completion object if the transfer wasn't async.
         * Otherwise, when we return the the sync function we'll get stuck in the sync wait loop.
         */
        if (spiDmaState->isTransferBlocking)
        {
            OSA_SemaPost(&spiDmaState->irqSync);
        }

        return kStatus_SPI_Success;
    }

    /* Configure bus for this device. If NULL is passed, we assume the caller has
     * preconfigured the bus using SPI_DRV_DmaMasterConfigureBus().
     * Do nothing for calculatedBaudRate. If the user wants to know the calculatedBaudRate
     * then they can call this function separately.
     */
    if (device)
    {
        SPI_DRV_DmaMasterConfigureBus(instance, device, &calculatedBaudRate);
    }

    /* In order to flush any remaining data in the shift register, disable then enable the SPI */
    SPI_HAL_Disable(base);
    SPI_HAL_Enable(base);

#if FSL_FEATURE_SPI_16BIT_TRANSFERS
    /* Check the transfer byte count. If bits/frame > 8, meaning 2 bytes, and if
     * the transfer byte count is an odd count we'll have to round down the RX transfer byte count
     * to the next lowest even number by one and assert a flag to indicate in the interrupt handler
     * that we take care of sending and receiving this last byte.  We'll round up TX byte count.
     */
    if (SPI_HAL_Get8or16BitMode(base) == kSpi16BitMode) /* Applies to 16-bit transfers */
    {
        /* Odd byte count for 16-bit transfers, set the extraByte flag */
        if (spiDmaState->remainingSendByteCount & 1UL) /* If odd byte count */
        {
            transferSizeInBytes = 2; /* Set transfer size to two bytes for the DMA operation */
            spiDmaState->extraByte = true; /* Set the extraByte flag */

            /* Round up TX byte count so when DMA completes, all data would've been sent */
            spiDmaState->remainingSendByteCount += 1U;

            /* Round down RX byte count which means at the end of the RX DMA transfer, we'll need
             * to set up an interrupt to get the last byte.
             */
            spiDmaState->remainingReceiveByteCount &= ~1U;

            /* Store the transfer byte count to the run-time state struct
             * for later use in the interrupt handler.
             */
            spiDmaState->transferByteCnt = spiDmaState->remainingSendByteCount;
        }
        /* Even byte count for 16-bit transfers, clear the extraByte flag */
        else
        {
            transferSizeInBytes = 2; /* Set transfer size to two bytes for the DMA operation */
            spiDmaState->extraByte = false; /* Clear the extraByte flag */
        }
    }
    else /* For 8-bit transfers */
    {
        transferSizeInBytes = 1;
        spiDmaState->extraByte = false;
    }
#else
    transferSizeInBytes = 1;
#endif

    param = (void *)(instance); /* For DMA callback, set "param" as the SPI instance number */

    /* Check that we're not busy.*/
    if (spiDmaState->isTransferInProgress)
    {
        return kStatus_SPI_Busy;
    }

    /* Save information about the transfer for use by the ISR.*/
    spiDmaState->isTransferInProgress = true;

    /************************************************************************************
     * Set up the RX DMA channel Transfer Control Descriptor (TCD)
     * Note, if there is no receive byte count, then bypass RX DMA set up.
     ***********************************************************************************/
    if (spiDmaState->remainingReceiveByteCount)
    {
        /* If no receive buffer then disable incrementing the destination and set the destination
         * to a temporary location
         */
        if (!spiDmaState->receiveBuffer)
        {
            /* Set up this channel's control which includes enabling the DMA interrupt */
            DMA_DRV_ConfigTransfer(&spiDmaState->dmaReceive,
                                   kDmaPeripheralToPeripheral,
                                   transferSizeInBytes,
                                   SPI_HAL_GetDataRegAddr(base), /* src is data register */
                                   (uint32_t)(&s_rxBuffIfNull), /* dest is temporary location */
                                   (uint32_t)(spiDmaState->remainingReceiveByteCount));
        }
        else
        {
            /* Set up this channel's control which includes enabling the DMA interrupt */
            DMA_DRV_ConfigTransfer(&spiDmaState->dmaReceive,
                                   kDmaPeripheralToMemory,
                                   transferSizeInBytes,
                                   SPI_HAL_GetDataRegAddr(base), /* src is data register */
                                   (uint32_t)(spiDmaState->receiveBuffer),/* dest is rx buffer */
                                   (uint32_t)(spiDmaState->remainingReceiveByteCount));
        }

        /* Dest size is always 1 byte on each transfer */
        DMA_DRV_SetDestTransferSize(&spiDmaState->dmaReceive, 1U);

        /* Enable the DMA peripheral request */
        DMA_DRV_StartChannel(&spiDmaState->dmaReceive);

        /* Register callback for DMA interrupt */
        DMA_DRV_RegisterCallback(&spiDmaState->dmaReceive, SPI_DRV_DmaMasterCallback, param);
    }

    /************************************************************************************
     * Set up the TX DMA channel Transfer Control Descriptor (TCD)
     * Note, if there is no source buffer (if user passes in NULL), then send zeros
     ***********************************************************************************/
    /* Per the reference manual, before enabling the SPI transmit DMA request, we first need
     * to read the status register and then write to the SPI data register.  Afterwards, we need
     * to decrement the sendByteCount and perform other driver maintenance functions.
     */

    /* Read the SPI Status register */
    SPI_HAL_IsTxBuffEmptyPending(base);

    /* Start the transfer by writing the first byte/word to the SPI data register.
     * If a send buffer was provided, the byte/word comes from there. Otherwise we just send zeros.
     * This will cause an immeidate transfer which in some cases may cause the RX DMA channel to
     * complete before having the chance to completely set up the TX DMA channel. As such, we'll
     * enable the RX DMA channel last.
     */
#if FSL_FEATURE_SPI_16BIT_TRANSFERS
    if (transferSizeInBytes == 2) /* 16-bit transfers for SPI16 module */
    {
        if (spiDmaState->sendBuffer)
        {
            s_byteToSend = *(spiDmaState->sendBuffer);
            SPI_HAL_WriteDataLow(base, s_byteToSend);
            ++spiDmaState->sendBuffer;

            s_byteToSend = *(spiDmaState->sendBuffer);
            SPI_HAL_WriteDataHigh(base, s_byteToSend);
            ++spiDmaState->sendBuffer;
        }
        else  /* Else, if no send buffer, write zeros */
        {
            SPI_HAL_WriteDataLow(base, s_byteToSend);
            SPI_HAL_WriteDataHigh(base, s_byteToSend);
        }
        spiDmaState->remainingSendByteCount -= 2;  /* Decrement the send byte count by 2 */
    }
    else /* 8-bit transfers for SPI16 module */
    {
        if (spiDmaState->sendBuffer)
        {
            s_byteToSend = *(spiDmaState->sendBuffer);
            ++spiDmaState->sendBuffer;
        }
        SPI_HAL_WriteDataLow(base, s_byteToSend); /* If no send buffer, s_byteToSend=0 */
        --spiDmaState->remainingSendByteCount; /* Decrement the send byte count */
    }
#else
    /* For SPI modules that do not support 16-bit transfers */
    if (spiDmaState->sendBuffer)
    {
        s_byteToSend = *(spiDmaState->sendBuffer);
        ++spiDmaState->sendBuffer;
    }
    SPI_HAL_WriteData(base, s_byteToSend); /* If no send buffer, s_byteToSend=0 */
    --spiDmaState->remainingSendByteCount; /* Decrement the send byte count */
#endif

    /* If there are no more bytes to send then return without setting up the TX DMA channel
     * and let the receive DMA channel complete the transfer if the RX DMA channel was setup.
     * If the RX DMA channel was not set up (due to odd byte count of 1 in 16-bit mode), enable
     * the interrupt to get the received byte.
     */
    if (!spiDmaState->remainingSendByteCount) /* No more bytes to send */
    {
        if (spiDmaState->remainingReceiveByteCount)
        {
            /* Enable the RX DMA channel request now  */
            SPI_HAL_SetRxDmaCmd(base, true);
            return kStatus_SPI_Success;
        }
        else /* If RX DMA chan not setup then enable the interrupt to get the received byte */
        {
            SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, true);
            return kStatus_SPI_Success;
        }
    }
    /* Else, since there are more bytes to send, go ahead and set up the TX DMA channel */
    else
    {
        /* If there is a send buffer, data comes from there, else send 0 */
        if (spiDmaState->sendBuffer)
        {
            /* Set up this channel's control which includes enabling the DMA interrupt */
            DMA_DRV_ConfigTransfer(&spiDmaState->dmaTransmit, kDmaMemoryToPeripheral,
                                   transferSizeInBytes,
                                   (uint32_t)(spiDmaState->sendBuffer),
                                   SPI_HAL_GetDataRegAddr(base),
                                   (uint32_t)(spiDmaState->remainingSendByteCount));
        }
        else /* Configure TX DMA channel to send zeros */
        {
            /* Set up this channel's control which includes enabling the DMA interrupt */
            DMA_DRV_ConfigTransfer(&spiDmaState->dmaTransmit, kDmaPeripheralToPeripheral,
                                   transferSizeInBytes,
                                   (uint32_t)(&s_byteToSend),
                                   SPI_HAL_GetDataRegAddr(base),
                                   (uint32_t)(spiDmaState->remainingSendByteCount));
        }

        /* Source size is only one byte on each transfer */
        DMA_DRV_SetSourceTransferSize(&spiDmaState->dmaTransmit, 1U);

        /* Enable the SPI TX DMA Request */
        SPI_HAL_SetTxDmaCmd(base, true);

        /* Enable the SPI RX DMA Request after the TX DMA request is enabled.  This is done to
         * make sure that the RX DMA channel does not end prematurely before we've completely set
         * up the TX DMA channel since part of the TX DMA set up involves placing 1 or 2 bytes of
         * data into the send data register which causes an immediate transfer.
         */
        SPI_HAL_SetRxDmaCmd(base, true);

        /* Enable the DMA peripheral request */
        DMA_DRV_StartChannel(&spiDmaState->dmaTransmit);
    }

    return kStatus_SPI_Success;
}
Exemple #22
0
OSStatus MicoUartSend( mico_uart_t uart, const void* data, uint32_t size )
{
//  /* Reset DMA transmission result. The result is assigned in interrupt handler */
   uart_interfaces[uart].tx_dma_result = kGeneralErr;
    uart = MICO_UART_1; //test
#ifndef NO_MICO_RTOS
      mico_rtos_lock_mutex(&uart_interfaces[uart].tx_mutex);
#endif

  MicoMcuPowerSaveConfig(false);  
#ifdef  UART_IRQ_APP
  if (UART_DRV_SendData(BOARD_APP_UART_INSTANCE, data, size) == kStatus_UART_Success){
#else 
  if (UART_DRV_EdmaSendData(BOARD_APP_UART_INSTANCE, data, size) == kStatus_UART_Success){
#endif
    
#if ADD_OS_CODE
        #ifndef NO_MICO_RTOS
            mico_rtos_set_semaphore( &uart_interfaces[ uart ].tx_complete );
        #else
            uart_interfaces[ uart ].rx_complete = true;
        #endif
#endif
  }  
#if ADD_OS_CODE
#ifndef NO_MICO_RTOS
  mico_rtos_get_semaphore( &uart_interfaces[ uart ].tx_complete, MICO_NEVER_TIMEOUT );
#else 
  while(uart_interfaces[ uart ].tx_complete == false);
  uart_interfaces[ uart ].tx_complete = false;
#endif
#endif
//  return uart_interfaces[uart].tx_dma_result; 
  MicoMcuPowerSaveConfig(true);
#ifndef NO_MICO_RTOS
    mico_rtos_unlock_mutex(&uart_interfaces[uart].tx_mutex);
#endif

  return kNoErr;
}

void UART_DRV_CompleteReceiveData(uint32_t instance)
{
    assert(instance < HW_UART_INSTANCE_COUNT);

    uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance];
    uint32_t baseAddr = g_uartBaseAddr[instance];
    mico_uart_t uart;
    
    if(instance == BOARD_APP_UART_INSTANCE) uart = MICO_UART_1;
    
    /* Disable receive data full interrupt */
    UART_HAL_SetRxDataRegFullIntCmd(baseAddr, false);

    /* Signal the synchronous completion object. */
    if (uartState->isRxBlocking)
    {
        OSA_SemaPost(&uartState->rxIrqSync);
        mico_rtos_set_semaphore(&uart_interfaces[uart].rx_complete); //OSA_SemaPost(&uartState->rxIrqSync);
    }

    /* Update the information of the module driver state */
    uartState->isRxBusy = false;
}
Exemple #23
0
/**
 * trigger the power task
 * by filling the semaphore the task is blocked on
 */
static void power_TriggerTask()
{
	OSA_SemaPost( &power_sema );
}
/* Semaphore */
uint32_t OS_Sem_post(os_sem_handle handle)
{
    return ((kStatus_OSA_Success == OSA_SemaPost((semaphore_t*) (handle))) ? OS_SEM_OK : OS_SEM_ERROR);
}