Пример #1
0
/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_read
* Returned Value   : Number of bytes read
* Comments         :
*    POSIX wrapper to perform SPI transfer storing received data into the buffer.
*    Returns number of bytes received.
*
*END*********************************************************************/
static _mqx_int _io_spi_read
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* [OUT] Where the characters are to be stored */
        char                       *data_ptr,

        /* [IN] The number of bytes to read */
        _mqx_int                       n
    )
{
	
	#if 0
    //SPI_DEV_DATA_STRUCT_PTR    dev_data;
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;
	_mqx_int num = n;

    //dev_data = (SPI_DEV_DATA_STRUCT_PTR)(fd_ptr->DEV_DATA_PTR);
    char tmp;
	driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(fd_ptr->DEV_PTR->DRIVER_INIT_PTR);
	_lwsem_wait(&driver_data->IRQ_SEM);
	/*add callback function here before real read*/	
	SPI_CS_CALLBACK_STRUCT	callback;
	callback.CALLBACK = read_cs_callback;
	callback.USERDATA = fd_ptr;
	_io_spi_ioctl(fd_ptr, IO_IOCTL_SPI_SET_CS_CALLBACK, &callback);
	while(lwgpio_get_value(&driver_data->SPI_IRQ_PIN) && num)
	{
		if(IO_ERROR !=_io_spi_read_write(fd_ptr, NULL, &tmp, 1))
		{	
			*data_ptr++ = tmp;
			num--;
		}
		else
			return IO_ERROR;
	}
	//return _io_spi_read_write(fd_ptr, NULL, data_ptr, n);
	_io_spi_flush(fd_ptr, 0);
	return (n-num);
	#endif
	return _io_spi_read_write(fd_ptr, NULL, data_ptr, n);
}
Пример #2
0
/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_write
* Returned Value   : Number of bytes to write
* Comments         :
*    POSIX wrapper to perform SPI transfer sending data from the buffer.
*    Returns number of bytes received.
*
*END**********************************************************************/
static _mqx_int _io_spi_write
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* [IN] Where the bytes are stored */
        char                       *data_ptr,

        /* [IN] The number of bytes to output */
        _mqx_int                       n
    )
{
	#if 0
    //return _io_spi_read_write(fd_ptr, data_ptr, NULL, n);
	if(IO_ERROR == _io_spi_read_write(fd_ptr, data_ptr, NULL, n))
		return IO_ERROR;
	_io_spi_flush(fd_ptr, 0);
	return MQX_OK;
	#endif
	return _io_spi_read_write(fd_ptr, data_ptr, NULL, n);
}
Пример #3
0
/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_write
* Returned Value   : Number of bytes to write
* Comments         :
*    POSIX wrapper to perform SPI transfer sending data from the buffer.
*    Returns number of bytes received.
*
*END**********************************************************************/
static _mqx_int _io_spi_write
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* [IN] Where the bytes are stored */
        char                       *data_ptr,

        /* [IN] The number of bytes to output */
        _mqx_int                       n
    )
{
    return _io_spi_read_write(fd_ptr, data_ptr, NULL, n);
}
Пример #4
0
/*FUNCTION****************************************************************
*
* Function Name    : _io_spi_read
* Returned Value   : Number of bytes read
* Comments         :
*    POSIX wrapper to perform SPI transfer storing received data into the buffer.
*    Returns number of bytes received.
*
*END*********************************************************************/
static _mqx_int _io_spi_read
    (
        /* [IN] The handle returned from _fopen */
        MQX_FILE_PTR                   fd_ptr,

        /* [OUT] Where the characters are to be stored */
        char                       *data_ptr,

        /* [IN] The number of bytes to read */
        _mqx_int                       n
    )
{
    return _io_spi_read_write(fd_ptr, NULL, data_ptr, n);
}
Пример #5
0
/*FUNCTION*****************************************************************
*
* Function Name    : _io_spi_ioctl
* Returned Value   : MQX error code
* Comments         :
*    Returns result of SPI ioctl operation.
*
*END*********************************************************************/
static _mqx_int _io_spi_ioctl
    (
        /* [IN] the file handle for the device */
        MQX_FILE_PTR                   fd_ptr,

        /* [IN] the ioctl command */
        uint32_t                        cmd,

        /* [IN] the ioctl parameters */
        void                          *param_ptr
    )
{
    SPI_DEV_DATA_STRUCT_PTR    dev_data;
    SPI_DRIVER_DATA_STRUCT_PTR driver_data;

    _mqx_int result = MQX_OK;
    _mqx_int lldrv_result = MQX_OK;

    dev_data = (SPI_DEV_DATA_STRUCT_PTR)(fd_ptr->DEV_DATA_PTR);
    driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(fd_ptr->DEV_PTR->DRIVER_INIT_PTR);

    switch (cmd) {

        case IO_IOCTL_DEVICE_IDENTIFY:
            /* return the device identification */
            ((_mqx_uint_ptr)param_ptr)[0] = IO_DEV_TYPE_PHYS_SPI;
            ((_mqx_uint_ptr)param_ptr)[1] = 0;
            ((_mqx_uint_ptr)param_ptr)[2] = IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
            break;

        case IO_IOCTL_FLUSH_OUTPUT:
            result = _io_spi_flush(fd_ptr, ((dev_data->FLAGS & SPI_FLAG_NO_DEASSERT_ON_FLUSH)!=0));
            break;

        case IO_IOCTL_SPI_FLUSH_DEASSERT_CS:
            result = _io_spi_flush(fd_ptr, 0);
            break;

        case IO_IOCTL_SPI_READ_WRITE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                SPI_READ_WRITE_STRUCT_PTR rw_ptr = (SPI_READ_WRITE_STRUCT_PTR)param_ptr;
                if (rw_ptr->BUFFER_LENGTH != _io_spi_read_write(fd_ptr, rw_ptr->WRITE_BUFFER, rw_ptr->READ_BUFFER, rw_ptr->BUFFER_LENGTH))
                    result = IO_ERROR;

            }
            break;

        case IO_IOCTL_SPI_GET_FLAGS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint32_t *)param_ptr) = dev_data->FLAGS;
            }
            break;

        case IO_IOCTL_SPI_SET_FLAGS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->FLAGS = *((uint32_t *)param_ptr);
            }
            break;

        case IO_IOCTL_SPI_GET_BAUD:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint32_t *)param_ptr) = dev_data->PARAMS.BAUDRATE;

                /* Pass IOCTL also to the low level driver */
                if (driver_data->DEVIF->IOCTL != NULL)
                    result = driver_data->DEVIF->IOCTL(driver_data->DEVIF_DATA, &(dev_data->PARAMS), cmd, param_ptr);

                /* Invalid IOCTL reported by the low level driver is not an error (implementation is not mandatory) */
                if (result == IO_ERROR_INVALID_IOCTL_CMD)
                    result = MQX_OK;
            }
            break;

        case IO_IOCTL_SPI_SET_BAUD:
            if (NULL == param_ptr || 0 == *((uint32_t *)param_ptr))
            {
                /* use default baudrate */
                dev_data->PARAMS.BAUDRATE = driver_data->PARAMS.BAUDRATE;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else
            {
                dev_data->PARAMS.BAUDRATE = *((uint32_t *)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint32_t *)param_ptr) = dev_data->PARAMS.MODE;
            }
            break;

        case IO_IOCTL_SPI_SET_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.MODE = *((uint32_t *)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint32_t *)param_ptr) = dev_data->PARAMS.CS;
            }
            break;

        case IO_IOCTL_SPI_SET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.CS = *((uint32_t *)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_FRAMESIZE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint32_t *)param_ptr) = dev_data->PARAMS.FRAMESIZE;
            }
            break;

        case IO_IOCTL_SPI_SET_FRAMESIZE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.FRAMESIZE = *((uint32_t *)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_GET_TRANSFER_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if ((dev_data->PARAMS.ATTR & SPI_ATTR_TRANSFER_MODE_MASK) == SPI_ATTR_SLAVE_MODE)
            {
                *((uint32_t *)param_ptr) = SPI_DEVICE_SLAVE_MODE;
            }
            else
            {
                *((uint32_t *)param_ptr) = SPI_DEVICE_MASTER_MODE;
            }
            break;

        case IO_IOCTL_SPI_SET_TRANSFER_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if (*((uint32_t *)param_ptr) == SPI_DEVICE_SLAVE_MODE)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_TRANSFER_MODE_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_SLAVE_MODE;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else if (*((uint32_t *)param_ptr) == SPI_DEVICE_MASTER_MODE)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_TRANSFER_MODE_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_MASTER_MODE;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else
            {
                result = SPI_ERROR_TRANSFER_MODE_INVALID;
            }
            break;

        case IO_IOCTL_SPI_GET_ENDIAN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if ((dev_data->PARAMS.ATTR & SPI_ATTR_ENDIAN_MASK) == SPI_ATTR_LITTLE_ENDIAN)
            {
                *((uint32_t *)param_ptr) = SPI_DEVICE_LITTLE_ENDIAN;
            }
            else
            {
                *((uint32_t *)param_ptr) = SPI_DEVICE_BIG_ENDIAN;
            }
            break;

        case IO_IOCTL_SPI_SET_ENDIAN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if (*((uint32_t *)param_ptr) == SPI_DEVICE_LITTLE_ENDIAN)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_ENDIAN_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_LITTLE_ENDIAN;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else if (*((uint32_t *)param_ptr) == SPI_DEVICE_BIG_ENDIAN)
            {
                dev_data->PARAMS.ATTR &= ~SPI_ATTR_ENDIAN_MASK;
                dev_data->PARAMS.ATTR |= SPI_ATTR_BIG_ENDIAN;
                dev_data->PARAMS_DIRTY = TRUE;
            }
            else
            {
                result = SPI_ERROR_ENDIAN_INVALID;
            }
            break;

        case IO_IOCTL_SPI_GET_DUMMY_PATTERN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((uint32_t *)param_ptr) = dev_data->PARAMS.DUMMY_PATTERN;
            }
            break;

        case IO_IOCTL_SPI_SET_DUMMY_PATTERN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                dev_data->PARAMS.DUMMY_PATTERN = *((uint32_t *)param_ptr);
                dev_data->PARAMS_DIRTY = TRUE;
            }
            break;

        case IO_IOCTL_SPI_SET_CS_CALLBACK:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                if (!(dev_data->BUS_OWNER) && ((result=_lwsem_wait(&(driver_data->BUS_LOCK))) != MQX_OK))
                    break;

                driver_data->CS_CALLBACK = ((SPI_CS_CALLBACK_STRUCT_PTR)param_ptr)->CALLBACK;
                driver_data->CS_USERDATA = ((SPI_CS_CALLBACK_STRUCT_PTR)param_ptr)->USERDATA;

                if (!(dev_data->BUS_OWNER))
                    result = _lwsem_post(&(driver_data->BUS_LOCK));
            }
            break;

        case IO_IOCTL_SPI_GET_STATS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                #if BSPCFG_ENABLE_SPI_STATS
                *((SPI_STATISTICS_STRUCT_PTR)param_ptr) = dev_data->STATS;
                #else
                _mem_zero(param_ptr, sizeof(SPI_STATISTICS_STRUCT));
                result = MQX_IO_OPERATION_NOT_AVAILABLE;
                #endif
            }
            break;

        case IO_IOCTL_SPI_CLEAR_STATS:
            #if BSPCFG_ENABLE_SPI_STATS
            _mem_zero(&(dev_data->STATS), sizeof(dev_data->STATS));
            #else
            result = MQX_IO_OPERATION_NOT_AVAILABLE;
            #endif
            break;

        case IO_IOCTL_SPI_DEVICE_ENABLE:
            break;

        case IO_IOCTL_SPI_DEVICE_DISABLE:
            break;

        default:
            /* Pass unhandled IOCTL to the low level driver */
            if (driver_data->DEVIF->IOCTL != NULL)
            {
                /* Do not assume that the low level driver is re-entrant, lock semaphore */
                if (!(dev_data->BUS_OWNER) && ((result=_lwsem_wait(&(driver_data->BUS_LOCK))) != MQX_OK))
                    break;

                lldrv_result = driver_data->DEVIF->IOCTL(driver_data->DEVIF_DATA, &(dev_data->PARAMS), cmd, param_ptr);

                if (!(dev_data->BUS_OWNER))
                    result = _lwsem_post(&(driver_data->BUS_LOCK));

                /* Report low level driver error, if any */
                if (lldrv_result != MQX_OK)
                    result = lldrv_result;
            }
            else
            {
                result = IO_ERROR_INVALID_IOCTL_CMD;
            }
            break;
    }

    return result;
}