Beispiel #1
0
uint32_t _kuart_mix_init
	(
	   /* [IN] the interrupt I/O initialization information */
	   IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

	   /* [IN] the rest of the name of the device opened */
	   char *                     open_name_ptr
	)
{ /* Body */
      KUART_INFO_STRUCT_PTR sci_info_ptr;
      KUART_INIT_STRUCT_PTR sci_init_ptr;
      uint32_t                     result = MQX_OK;

      //Init basic uart setting
      sci_init_ptr = int_io_dev_ptr->DEV_INIT_DATA_PTR;
      result = _kuart_polled_init((void *)sci_init_ptr, &int_io_dev_ptr->DEV_INFO_PTR, open_name_ptr);
      if (result != MQX_OK) {
          return(result);
      }/* Endif */
      sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
      sci_info_ptr->RX_KEEP = 1;

      /* Add a timer config to check the UART RX state */    
      sci_info_ptr->LW_TIMER_PTR = (LWTIMER_PERIOD_STRUCT_PTR)_mem_alloc_system_zero(sizeof(LWTIMER_PERIOD_STRUCT) + sizeof(LWTIMER_STRUCT));
      if (!sci_info_ptr->LW_TIMER_PTR)
      {
          result = MQX_OUT_OF_MEMORY;
          goto error_free_timer;
      }
      sci_info_ptr->LW_TIMER = (LWTIMER_STRUCT_PTR)((uint8_t *)sci_info_ptr->LW_TIMER_PTR + sizeof(LWTIMER_PERIOD_STRUCT));
      _time_init_ticks(&sci_info_ptr->ticks, 1);  
      _lwtimer_create_periodic_queue(sci_info_ptr->LW_TIMER_PTR ,*(uint32_t *)(&sci_info_ptr->ticks), 0);

      _lwtimer_add_timer_to_queue(
              sci_info_ptr->LW_TIMER_PTR, 
              sci_info_ptr->LW_TIMER,
              0,
              _kuart_period_isr,
              (void *)int_io_dev_ptr);

      /* RX DMA setting */
      sci_info_ptr->RX_BUF = _mem_alloc_system_zero_uncached(sci_init_ptr->IQUEUE_SIZE);
      sci_info_ptr->RX_ACTIVE = sci_info_ptr->RX_BUF;
      if (!sci_info_ptr->RX_BUF)
      {
              result = MQX_OUT_OF_MEMORY;
              goto error_free_buf;
      }
      sci_info_ptr->RX_DMA_CHAN = sci_init_ptr->RX_DMA_CHANNEL;
      sci_info_ptr->RX_DMA_HARDWARE_REQUEST = _bsp_get_serial_rx_dma_request(sci_init_ptr->DEVICE);
#if PSP_MQX_CPU_IS_KINETIS
      sci_info_ptr->ERR_INT = _bsp_get_serial_error_int_num(sci_init_ptr->DEVICE);
#endif
    sci_info_ptr->RX_DMA_SEQ = 0;
    result = dma_channel_claim(&sci_info_ptr->RX_DCH, sci_info_ptr->RX_DMA_CHAN);
    if (result != MQX_OK)
    {
            goto error_free_channel;
    }
    result = dma_callback_reg(sci_info_ptr->RX_DCH, _kuart_dma_rx_isr, int_io_dev_ptr);
    dma_channel_setup(sci_info_ptr->RX_DCH, 1, DMA_CHANNEL_FLAG_LOOP_MODE);
    dma_request_source(sci_info_ptr->RX_DCH, sci_info_ptr->RX_DMA_HARDWARE_REQUEST);

    if (result != MQX_OK)
    {
            goto error_free_channel;
    }


    /* Init RX/TX interrupt vector */

    sci_info_ptr->OLD_ISR_TXRX_DATA = _int_get_isr_data(sci_init_ptr->RX_TX_VECTOR);
    sci_info_ptr->OLD_ISR_EXCEPTION_HANDLER = _int_get_exception_handler(sci_init_ptr->RX_TX_VECTOR);

    sci_info_ptr->OLD_ISR_TXRX =
    _int_install_isr(sci_init_ptr->RX_TX_VECTOR, _kuart_mix_int_tx_isr, int_io_dev_ptr);
    _bsp_int_init(sci_init_ptr->RX_TX_VECTOR, sci_init_ptr->RX_TX_PRIORITY, 0, TRUE);


    /* Init mix error vector */
    sci_info_ptr->OLD_ISR_ERR =
    _int_install_isr(sci_info_ptr->ERR_INT, _kuart_mix_err_isr, int_io_dev_ptr);
    _bsp_int_init(sci_info_ptr->ERR_INT, sci_init_ptr->ERR_PRIORITY, 0, TRUE);

    /* config the UART RX channel first */
    _kuart_prepare_rx_dma(int_io_dev_ptr);      
    return(MQX_OK);

error_free_timer:
    if (!sci_info_ptr->LW_TIMER_PTR)
    _mem_free(sci_info_ptr->LW_TIMER_PTR);

error_free_channel:
    dma_channel_release(sci_info_ptr->RX_DCH);
    
error_free_buf:
    if (sci_info_ptr->RX_BUF)
            _mem_free(sci_info_ptr->RX_BUF);

    return result;
} /* Endbody */
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_dma_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes the SPI driver
*
*END*********************************************************************/
static _mqx_int _dspi_dma_init
    (
        /* [IN] The initialization information for the device being opened */
        const void                     *init_data_ptr,

        /* [OUT] The address to store device specific information */
        void                           **io_info_ptr_ptr
    )
{
    DSPI_DMA_INIT_STRUCT_PTR           dspi_init_ptr = (DSPI_DMA_INIT_STRUCT_PTR)init_data_ptr;
    DSPI_DMA_INFO_STRUCT_PTR           dspi_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr;
    int                                result;

    #if PSP_HAS_DEVICE_PROTECTION
    if (!_bsp_dspi_enable_access(dspi_init_ptr->CHANNEL)) {
        return SPI_ERROR_CHANNEL_INVALID;
    }
    #endif

    /* Check channel */
    dspi_ptr = _bsp_get_dspi_base_address (dspi_init_ptr->CHANNEL);
    if (NULL == dspi_ptr)
    {
        return SPI_ERROR_CHANNEL_INVALID;
    }

    if (_bsp_dspi_io_init (dspi_init_ptr->CHANNEL) == -1)
    {
        return SPI_ERROR_CHANNEL_INVALID;
    }

    /* Initialize internal data */
    dspi_info_ptr = (DSPI_DMA_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint32_t)sizeof(DSPI_DMA_INFO_STRUCT));
    if (dspi_info_ptr == NULL)
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type(dspi_info_ptr, MEM_TYPE_IO_SPI_INFO_STRUCT);

    *io_info_ptr_ptr = (void *)dspi_info_ptr;

    dspi_info_ptr->DSPI_PTR = dspi_ptr;
    dspi_info_ptr->CHANNEL = dspi_init_ptr->CHANNEL;
    dspi_info_ptr->CLOCK_SOURCE = dspi_init_ptr->CLOCK_SOURCE;

    _dspi_init_low(dspi_info_ptr->DSPI_PTR);

    /* Claim DMA channels and perform setup */
    if ((result = dma_channel_claim(&dspi_info_ptr->DMA_RX_CHANNEL, dspi_init_ptr->DMA_RX_CHANNEL)) != MQX_OK
        || (result = dma_channel_claim(&dspi_info_ptr->DMA_TX_CHANNEL, dspi_init_ptr->DMA_TX_CHANNEL)) != MQX_OK
        || (result = dma_channel_setup(dspi_info_ptr->DMA_RX_CHANNEL, 1, 0)) != MQX_OK
        || (result = dma_channel_setup(dspi_info_ptr->DMA_TX_CHANNEL, 1, 0)) != MQX_OK
        || (result = dma_request_source(dspi_info_ptr->DMA_RX_CHANNEL, dspi_init_ptr->DMA_RX_SOURCE)) != MQX_OK
        || (result = dma_request_source(dspi_info_ptr->DMA_TX_CHANNEL, dspi_init_ptr->DMA_TX_SOURCE)) != MQX_OK
       )
    {
        dma_channel_release(dspi_info_ptr->DMA_RX_CHANNEL);
        dma_channel_release(dspi_info_ptr->DMA_TX_CHANNEL);
        _mem_free(dspi_info_ptr);
        return result;
    }

    /* Allocate cache line aligned block of memory and split it in half to form RX and TX buffer */
    dspi_info_ptr->RX_BUF = _mem_alloc_system(4*PSP_CACHE_LINE_SIZE);
    if (dspi_info_ptr->RX_BUF == NULL)
    {
        dma_channel_release(dspi_info_ptr->DMA_RX_CHANNEL);
        dma_channel_release(dspi_info_ptr->DMA_TX_CHANNEL);
        _mem_free(dspi_info_ptr);
        return MQX_OUT_OF_MEMORY;
    }
    dspi_info_ptr->TX_BUF = dspi_info_ptr->RX_BUF + 2*PSP_CACHE_LINE_SIZE;

    _lwsem_create(&dspi_info_ptr->EVENT_IO_FINISHED, 0);

    dma_callback_reg(dspi_info_ptr->DMA_RX_CHANNEL, _dspi_dma_callback, dspi_info_ptr);

    /* Route data s to DMA */
    dspi_ptr->RSER = DSPI_RSER_RFDF_DIRS_MASK | DSPI_RSER_RFDF_RE_MASK | DSPI_RSER_TFFF_DIRS_MASK | DSPI_RSER_TFFF_RE_MASK;
    dma_request_enable(dspi_info_ptr->DMA_RX_CHANNEL);
    dma_request_enable(dspi_info_ptr->DMA_TX_CHANNEL);

    return SPI_OK;
}