Пример #1
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_period_isr
* Returned Value   : void
* Comments         :
*    Periodic interrupt for mix uart.
*
*END*----------------------------------------------------------------------*/
static void _kuart_period_isr(void * data_ptr) {
    IO_SERIAL_INT_DEVICE_STRUCT_PTR        int_io_dev_ptr = data_ptr;
    KUART_INFO_STRUCT_PTR                  sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    uint32_t dmaUC, dmaC;

    _int_disable();

    dma_channel_status(sci_info_ptr->RX_DCH, &sci_info_ptr->RX_DMA_SEQ, &dmaUC);
    dmaC = int_io_dev_ptr->IQUEUE_SIZE - dmaUC;


    if (_QUEUE_GET_SIZE(int_io_dev_ptr->IN_WAITING_TASKS)) {
        if((int64_t)(dmaC + sci_info_ptr->dmaC - sci_info_ptr->readC) >= sci_info_ptr->rxwakeupnum){
            _taskq_resume(int_io_dev_ptr->IN_WAITING_TASKS, TRUE);
        }
    }

    _int_enable();
}
Пример #2
0
_mqx_int _io_serial_mix_read
   (
      /* [IN] the handle returned from _fopen */
      FILE_DEVICE_STRUCT_PTR fd_ptr,

      /* [IN] where the characters are to be stored */
      char              *data_ptr,

      /* [IN] the number of characters to input */
      _mqx_int               num
      
   )
{ /* Body */
   IO_DEVICE_STRUCT_PTR            io_dev_ptr;
   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr;
   KUART_INFO_STRUCT_PTR           sci_info_ptr;

   uint32_t                        dmaUC     = 0, dmaC = 0;
   uint32_t                        queueSize = 0;
   uint8_t                        *dmaBuffer = NULL;
   uint32_t                        dmaOff = 0, readOff = 0;


   io_dev_ptr     =             fd_ptr->DEV_PTR;
   int_io_dev_ptr = (void *)io_dev_ptr->DRIVER_INIT_PTR;
   sci_info_ptr   =     int_io_dev_ptr->DEV_INFO_PTR;

   queueSize =  int_io_dev_ptr->IQUEUE_SIZE;
   dmaBuffer = (uint8_t *)sci_info_ptr->RX_BUF;


   _int_disable();
   dma_channel_status(sci_info_ptr->RX_DCH, &sci_info_ptr->RX_DMA_SEQ, &dmaUC);
   dmaC = queueSize - dmaUC;

#if 1
   if((int64_t)(dmaC + sci_info_ptr->dmaC - sci_info_ptr->readC) < num){
       sci_info_ptr->rxwakeupnum = num;
       _int_enable();
       _taskq_suspend(int_io_dev_ptr->IN_WAITING_TASKS);
       _int_disable();
       dma_channel_status(sci_info_ptr->RX_DCH, &sci_info_ptr->RX_DMA_SEQ, &dmaUC);
       dmaC = queueSize - dmaUC;
   }
#endif
#if 0
   while((int64_t)(dmaC + sci_info_ptr->dmaC - sci_info_ptr->readC) < num){
       sci_info_ptr->rxwakeupnum = num;
       _int_enable();
       _taskq_suspend(int_io_dev_ptr->IN_WAITING_TASKS);
       //_sched_yield();
       _int_disable();
       dma_channel_status(sci_info_ptr->RX_DCH, &sci_info_ptr->RX_DMA_SEQ, &dmaUC);
       dmaC = queueSize - dmaUC;
   }
#endif

   if((int64_t)(dmaC + sci_info_ptr->dmaC - sci_info_ptr->readC) > queueSize){
       printf("UART dma buffer full! Reset read header. \n");
       sci_info_ptr->readC = dmaC + sci_info_ptr->dmaC - num;
   }


   dmaOff  = (dmaC + sci_info_ptr->dmaC) % queueSize;
   readOff =  sci_info_ptr->readC % queueSize;

   if(readOff + num > queueSize){
       memcpy(data_ptr,                       dmaBuffer + readOff, queueSize - readOff);
       memcpy(data_ptr + queueSize - readOff, dmaBuffer,           readOff + num - queueSize);

   }else{
       memcpy(data_ptr, dmaBuffer + readOff, num);
   }

   sci_info_ptr->readC += num;
   _int_enable();
   //printf("mix read %d bytes, dmaC %d \n", num, dmaC);

   return num;

} /* Endbody */
Пример #3
0
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_dma_transfer
* Returned Value   : number of bytes transferred
* Comments         :
*   Internal routine performing actual DMA transfer of given width
*   If txbuf is NULL the function expects dummy pattern already prepared in dspi_info_ptr->TX_BUFFER
*
*END*********************************************************************/
static _mqx_int _dspi_dma_transfer
    (
        /* [IN] Device specific context structure */
        DSPI_DMA_INFO_STRUCT_PTR       dspi_info_ptr,

        /* [IN] Data to transmit */
        uint8_t                     *txbuf,

        /* [OUT] Received data */
        uint8_t                     *rxbuf,

        /* [IN] Length of transfer in bytes */
        uint32_t                        len,

        /* [IN] Width of data register access for DMA transfer */
        int                            regw
    )
{
    DMA_TCD                            tx_tcd;
    DMA_TCD                            rx_tcd;

    #if PSP_ENDIAN == MQX_LITTLE_ENDIAN
        if (regw > 1) {
            regw = -regw;
        }
    #endif

    if (NULL != rxbuf) {
        dma_tcd_reg2mem(&rx_tcd, &(dspi_info_ptr->DSPI_PTR->POPR), regw, rxbuf, len);
    }
    else {
        dma_tcd_reg2mem(&rx_tcd, &(dspi_info_ptr->DSPI_PTR->POPR), regw, dspi_info_ptr->RX_BUF, len);
        rx_tcd.LOOP_DST_OFFSET = -regw;
    }

    if (NULL != txbuf) {
        dma_tcd_mem2reg(&tx_tcd, &(dspi_info_ptr->DSPI_PTR->PUSHR), regw, txbuf, len);
    }
    else {
        dma_tcd_mem2reg(&tx_tcd, &(dspi_info_ptr->DSPI_PTR->PUSHR), regw, dspi_info_ptr->TX_BUF, len);
        tx_tcd.LOOP_SRC_OFFSET = -regw;
    }

    /* ensure that the semaphore is at zero count */
    while (_lwsem_poll(&dspi_info_ptr->EVENT_IO_FINISHED)) {}

    dma_transfer_submit(dspi_info_ptr->DMA_RX_CHANNEL, &rx_tcd, NULL);
    dma_transfer_submit(dspi_info_ptr->DMA_TX_CHANNEL, &tx_tcd, NULL);

    /* block the task until completion of the background operation */
    _lwsem_wait(&dspi_info_ptr->EVENT_IO_FINISHED);

    if (dma_channel_status(dspi_info_ptr->DMA_RX_CHANNEL, NULL, NULL)
        || dma_channel_status(dspi_info_ptr->DMA_TX_CHANNEL, NULL, NULL)
       )
    {
        return 0;
    }

    return len;
}