コード例 #1
0
ファイル: spi_dspi.c プロジェクト: BillyZhangZ/wifi
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes the SPI driver
*
*END*********************************************************************/
static _mqx_int _dspi_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_INIT_STRUCT_PTR               dspi_init_ptr = (DSPI_INIT_STRUCT_PTR)init_data_ptr;

    DSPI_INFO_STRUCT_PTR               dspi_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr;

    const uint32_t                     *vectors;
    uint32_t                            i;

    #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_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint32_t)sizeof(DSPI_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);

    _lwsem_create(&dspi_info_ptr->EVENT_IO_FINISHED, 0);

    /* Install ISRs */
    dspi_info_ptr->NUM_VECTORS = _bsp_get_dspi_vectors(dspi_info_ptr->CHANNEL, &vectors);

    for (i=0; i<dspi_info_ptr->NUM_VECTORS; i++)
    {
        _int_install_isr(vectors[i], _dspi_isr, dspi_info_ptr);
        _bsp_int_init((PSP_INTERRUPT_TABLE_INDEX)vectors[i], BSP_DSPI_INT_LEVEL, 0, TRUE);
    }


    return SPI_OK;
}
コード例 #2
0
/*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;
}