/*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); } }
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; } }
/** * 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; } }
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; }
/*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; }
/*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; } }
/*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); }
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; }
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; }
/** * 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); }