Esempio n. 1
0
static _mqx_int write_cs_callback(uint32_t pre_cfg_mask, void *user_data)
{
	VDSPI_REG_STRUCT_PTR               dspi_ptr;
	LWGPIO_STRUCT  em9301_spi_mosi;
	if(pre_cfg_mask & PRE_CONFIGURE_FLAG)
	{
		dspi_ptr = _bsp_get_dspi_base_address(1);
		dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(0xFF);
		/*MOSI set pin*/
		lwgpio_init(&em9301_spi_mosi, BSP_EM9301_MOSI_PIN, LWGPIO_DIR_OUTPUT, LWGPIO_VALUE_NOCHANGE);
		lwgpio_set_functionality(&em9301_spi_mosi, 1);
		lwgpio_set_value(&em9301_spi_mosi, 1);
		/*Assert CS pin*/
		dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(~0x01);
		lwgpio_set_functionality(&em9301_spi_mosi, 7);
	}
	return MQX_OK;
}
Esempio n. 2
0
static _mqx_int read_cs_callback(uint32_t pre_cfg_mask, void *user_data)
{		
	
	BleStatus				status;
	MQX_FILE_PTR					dev = (MQX_FILE_PTR)user_data; 
	SPI_DEV_DATA_STRUCT_PTR			dev_data = (SPI_DEV_DATA_STRUCT_PTR)(dev->DEV_DATA_PTR);

	U8 byteReceievd;
	VDSPI_REG_STRUCT_PTR               dspi_ptr;  
	LWGPIO_STRUCT  em9301_spi_mosi;
	if(pre_cfg_mask & PRE_CONFIGURE_FLAG)
	{
		dspi_ptr = _bsp_get_dspi_base_address(1);    
		dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(0xFF);
		lwgpio_init(&em9301_spi_mosi, BSP_EM9301_MOSI_PIN, LWGPIO_DIR_OUTPUT, LWGPIO_VALUE_NOCHANGE);
		lwgpio_set_functionality(&em9301_spi_mosi, 1);
		lwgpio_set_value(&em9301_spi_mosi, 0);		
		/*Assert CS pin*/ 	
		dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK;	
		dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(~0x01);
		lwgpio_set_functionality(&em9301_spi_mosi, 7);	
	}
	else
	{
		if(dev_data->STATS.RX_PACKETS)
		{
			if(dev_data->STATS.RX_PACKETS >= EM9301_READ_BUFFER_SIZE)
			{
				status = BLETRANSPORT_UartDataReceived(hciBuffer, dev_data->STATS.RX_PACKETS);
				if(status == BLESTATUS_FAILED)
				{
					BLEUART_Deinit();
					return BLESTATUS_FAILED;					
				}			
			}
			byteReceievd = dev_data->STATS.RX_PACKETS;
			status = BLETRANSPORT_UartDataReceived(hciBuffer, byteReceievd);			
			if(SPI_OK != ioctl(dev, IO_IOCTL_SPI_CLEAR_STATS, 0))
				status = BLESTATUS_FAILED;
		}			
        
	}	
	return status;
}
Esempio n. 3
0
/*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;
}
Esempio n. 4
0
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_polled_init
* Returned Value   : MQX error code
* Comments         :
*    This function initializes the SPI module
*
*END*********************************************************************/
uint_32 _dspi_polled_init
    (
        /* [IN] The initialization information for the device being opened */
        DSPI_INIT_STRUCT_PTR          dspi_init_ptr,

        /* [OUT] The address to store device specific information */
        pointer _PTR_                 io_info_ptr_ptr,

        /* [IN] The rest of the name of the device opened */
        char_ptr                      open_name_ptr
    )
{
    VDSPI_REG_STRUCT_PTR              dspi_ptr;
    DSPI_INFO_STRUCT_PTR              io_info_ptr;
    uint_32                           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;
    }

    // Disable and clear SPI
    dspi_ptr->MCR &= (~ DSPI_MCR_MDIS_MASK);
    dspi_ptr->MCR = DSPI_MCR_HALT_MASK | DSPI_MCR_CLR_TXF_MASK | DSPI_MCR_CLR_RXF_MASK | DSPI_MCR_DIS_RXF_MASK | DSPI_MCR_DIS_TXF_MASK;

    /* Initialize internal data */
    io_info_ptr = (DSPI_INFO_STRUCT_PTR)_mem_alloc_system_zero((uint_32)sizeof(DSPI_INFO_STRUCT));
    if (io_info_ptr == NULL)
    {
        return MQX_OUT_OF_MEMORY;
    }
    _mem_set_type (io_info_ptr,MEM_TYPE_IO_SPI_INFO_STRUCT);

    *io_info_ptr_ptr = io_info_ptr;

    io_info_ptr->DSPI_PTR           = dspi_ptr;
    io_info_ptr->INIT               = *dspi_init_ptr;
    io_info_ptr->RX_REQUEST         = 0;
    io_info_ptr->RX_BUFFER          = NULL;
    io_info_ptr->RX_IN              = 0;
    io_info_ptr->RX_OUT             = 0;
    io_info_ptr->RX_COUNT           = 0;
    io_info_ptr->RX_DATA            = 0;
    io_info_ptr->TX_BUFFER          = NULL;
    io_info_ptr->TX_IN              = 0;
    io_info_ptr->TX_OUT             = 0;
    io_info_ptr->TX_COUNT           = 0;
    io_info_ptr->TX_DATA            = DSPI_PUSHR_CONT_MASK | DSPI_PUSHR_PCS(0) | DSPI_PUSHR_CTAS(0) | DSPI_PUSHR_TXDATA(0xFFFF);
    io_info_ptr->DMA_FLAGS          = 0;
    io_info_ptr->CS                 = DSPI_PUSHR_PCS_GET(dspi_init_ptr->CS);
    io_info_ptr->CS_ACTIVE          = 0;
    for (i = 0; i < DSPI_CS_COUNT; i++)
    {
        io_info_ptr->CS_CALLBACK[i] = NULL;
        io_info_ptr->CS_USERDATA[i] = NULL;
    }
    io_info_ptr->STATS.INTERRUPTS   = 0;
    io_info_ptr->STATS.RX_PACKETS   = 0;
    io_info_ptr->STATS.RX_OVERFLOWS = 0;
    io_info_ptr->STATS.TX_PACKETS   = 0;
    io_info_ptr->STATS.TX_ABORTS    = 0;
    io_info_ptr->STATS.TX_UNDERFLOWS= 0;

    /* Set the SPI clock baud rate divider */
    dspi_ptr->CTAR[0] = DSPI_CTAR_FMSZ(7);
    dspi_ptr->CTAR[0] |= _dspi_find_baudrate (dspi_init_ptr->CLOCK_SPEED, dspi_init_ptr->BAUD_RATE);

    /* Set up SPI clock polarity and phase */
    switch (dspi_init_ptr->CLOCK_POL_PHASE)
    {
        case (SPI_CLK_POL_PHA_MODE0):
            /* Inactive state of SPI_CLK = logic 0 */
            dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPOL_MASK);
            /* SPI_CLK transitions middle of bit timing */
            dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPHA_MASK);
            break;
        case (SPI_CLK_POL_PHA_MODE1):
            /* Inactive state of SPI_CLK = logic 0 */
            dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPOL_MASK);
            /* SPI_CLK transitions begining of bit timing */
            dspi_ptr->CTAR[0] |= DSPI_CTAR_CPHA_MASK;
            break;
        case (SPI_CLK_POL_PHA_MODE2):
            /* Inactive state of SPI_CLK = logic 1 */
            dspi_ptr->CTAR[0] |= DSPI_CTAR_CPOL_MASK;
            /* SPI_CLK transitions middle of bit timing */
            dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_CPHA_MASK);
            break;
        case (SPI_CLK_POL_PHA_MODE3):
            /* Inactive state of SPI_CLK = logic 1 */
            dspi_ptr->CTAR[0] |= DSPI_CTAR_CPOL_MASK;
            /* SPI_CLK transitions begining of bit timing */
            dspi_ptr->CTAR[0] |= DSPI_CTAR_CPHA_MASK;
            break;
        default:
            _mem_free (*io_info_ptr_ptr);
            *io_info_ptr_ptr = NULL;
            return SPI_ERROR_MODE_INVALID;
    }

    /* Receive FIFO overflow disable */
    dspi_ptr->MCR |= DSPI_MCR_ROOE_MASK;

    /* Set CS0-7 inactive high */
    dspi_ptr->MCR |= DSPI_MCR_PCSIS(0xFF);

    /* Set transfer mode */
    if (dspi_init_ptr->TRANSFER_MODE == SPI_DEVICE_SLAVE_MODE)
    {
        dspi_ptr->MCR &= (~ DSPI_MCR_MSTR_MASK);
    }
    else if (dspi_init_ptr->TRANSFER_MODE == SPI_DEVICE_MASTER_MODE)
    {
        dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK;
    }
    else
    {
        _mem_free (*io_info_ptr_ptr);
        *io_info_ptr_ptr = NULL;
        return SPI_ERROR_TRANSFER_MODE_INVALID;
    }

    /* Disable interrupts */
    dspi_ptr->RSER = 0;

    /* Clear all flags */
    dspi_ptr->SR = ~ DSPI_SR_TFFF_MASK;

    /* Enable SPI */
    dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);

    return SPI_OK;
}
Esempio n. 5
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;
}