コード例 #1
0
ファイル: spi_pol_dspi.c プロジェクト: jewlenchow/MQX_3.8.1
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_polled_ioctl
* Returned Value   : MQX error code
* Comments         :
*    This function performs miscellaneous services for
*    the SPI I/O device.
*
*END*********************************************************************/
uint_32 _dspi_polled_ioctl
    (
        /* [IN] The address of the device specific information */
        DSPI_INFO_STRUCT_PTR         io_info_ptr,

        /* [IN] The command to perform */
        uint_32                      cmd,

        /* [IN] Parameters for the command */
        uint_32_ptr                  param_ptr,

        /* [IN] Opening flags */
        uint_32                      flags
    )
{
    VDSPI_REG_STRUCT_PTR             dspi_ptr;
    SPI_CS_CALLBACK_STRUCT_PTR       callbacks;
    uint_32                          val, num;
    uint_32                          result = SPI_OK;
    SPI_READ_WRITE_STRUCT_PTR        rw_ptr;

    dspi_ptr = io_info_ptr->DSPI_PTR;

    switch (cmd)
    {
        case IO_IOCTL_SPI_GET_BAUD:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                val = dspi_ptr->CTAR[0];
                val = (BAUDRATE_PRESCALER[DSPI_CTAR_PBR_GET(val)] * BAUDRATE_SCALER[DSPI_CTAR_BR_GET(val)]) >> ((val & DSPI_CTAR_DBR_MASK) != 0);
                *param_ptr = (uint_32)((io_info_ptr->INIT.CLOCK_SPEED) / val);
            }
            break;
        case IO_IOCTL_SPI_SET_BAUD:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if (0 == (*param_ptr))
            {
                result = SPI_ERROR_BAUD_RATE_INVALID;
            }
            else
            {
                /* Disable SPI module */
                dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;
                /* Read current settings and clear those to be changed */
                val = dspi_ptr->CTAR[0];
                val &= ~(DSPI_CTAR_PBR_MASK | DSPI_CTAR_BR_MASK | DSPI_CTAR_DBR_MASK);
                val &= ~(DSPI_CTAR_PCSSCK_MASK | DSPI_CTAR_CSSCK_MASK);
                val &= ~(DSPI_CTAR_PASC_MASK | DSPI_CTAR_ASC_MASK);
                val &= ~(DSPI_CTAR_PDT_MASK | DSPI_CTAR_DT_MASK);
                /* Calculate dividers */
                val |= _dspi_find_baudrate (io_info_ptr->INIT.CLOCK_SPEED, *param_ptr);
                /* Write settins to register */
                dspi_ptr->CTAR[0] = val;
                /* Re-enable SPI module */
                dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_DEVICE_DISABLE:
            dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;
            break;
        case IO_IOCTL_SPI_DEVICE_ENABLE:
            dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);
            break;
        case IO_IOCTL_SPI_GET_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                if (dspi_ptr->CTAR[0] & DSPI_CTAR_CPOL_MASK)
                {
                    if (dspi_ptr->CTAR[0] & DSPI_CTAR_CPHA_MASK)
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE3;
                    }
                    else
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE2;
                    }
                }
                else
                {
                    if (dspi_ptr->CTAR[0] & DSPI_CTAR_CPHA_MASK)
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE1;
                    }
                    else
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE0;
                    }
                }
            }
            break;
        case IO_IOCTL_SPI_SET_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                /* Disable SPI module */
                dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;
                switch (*param_ptr)
                {
                    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:
                        result = SPI_ERROR_MODE_INVALID;
                        break;
                }
                /* Enable SPI module */
                dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_GET_TRANSFER_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                if (dspi_ptr->MCR & DSPI_MCR_MSTR_MASK)
                {
                    *param_ptr = SPI_DEVICE_MASTER_MODE;
                }
                else
                {
                    *param_ptr = SPI_DEVICE_SLAVE_MODE;
                }
            }
            break;
        case IO_IOCTL_SPI_SET_TRANSFER_MODE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                /* Disable SPI module */
                dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;
                /* Set transfer mode */
                if (*param_ptr == SPI_DEVICE_SLAVE_MODE)
                {
                    dspi_ptr->MCR &= (~ DSPI_MCR_MSTR_MASK);
                }
                else if (*param_ptr == SPI_DEVICE_MASTER_MODE)
                {
                    dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK;
                }
                else
                {
                    result = SPI_ERROR_TRANSFER_MODE_INVALID;
                }
                /* Enable SPI module */
                dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_GET_ENDIAN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if (dspi_ptr->CTAR[0] & DSPI_CTAR_LSBFE_MASK)
            {
                *param_ptr = SPI_DEVICE_LITTLE_ENDIAN;
            }
            else
            {
                *param_ptr = SPI_DEVICE_BIG_ENDIAN;
            }
            break;
        case IO_IOCTL_SPI_SET_ENDIAN:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else if (! (dspi_ptr->MCR & DSPI_MCR_MSTR_MASK))
            {
                result = SPI_ERROR_ENDIAN_INVALID;
            }
            else if (*param_ptr == SPI_DEVICE_LITTLE_ENDIAN)
            {
                dspi_ptr->CTAR[0] |= DSPI_CTAR_LSBFE_MASK;
            }
            else if (*param_ptr == SPI_DEVICE_BIG_ENDIAN)
            {
                dspi_ptr->CTAR[0] &= (~ DSPI_CTAR_LSBFE_MASK);
            }
            else
            {
                result = SPI_ERROR_ENDIAN_INVALID;
            }
            break;
        case IO_IOCTL_SPI_GET_STATS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *((SPI_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATS;
            }
            break;
        case IO_IOCTL_SPI_CLEAR_STATS:
            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;
            break;
        case IO_IOCTL_FLUSH_OUTPUT:
        case IO_IOCTL_SPI_FLUSH_DEASSERT_CS:
            while ((io_info_ptr->RX_COUNT) || (io_info_ptr->TX_COUNT) || (io_info_ptr->DMA_FLAGS))
                {};  // waiting for completion
            if ((0 == (flags & SPI_FLAG_NO_DEASSERT_ON_FLUSH)) || (IO_IOCTL_SPI_FLUSH_DEASSERT_CS == cmd))
            {
                /* Deassert all chip selects */
                if (dspi_ptr->MCR & DSPI_MCR_MSTR_MASK)
                {
                    _dspi_polled_cs(io_info_ptr, 0);
                    dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;
                    dspi_ptr->MCR &= (~ DSPI_MCR_MSTR_MASK);
                    dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK;
                    dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);
                }
            }
            break;
        case IO_IOCTL_SPI_GET_FRAMESIZE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = DSPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) + 1;
            }
            break;
        case IO_IOCTL_SPI_SET_FRAMESIZE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                /* Disable SPI module */
                dspi_ptr->MCR |= DSPI_MCR_HALT_MASK;
                dspi_ptr->CTAR[0] &= (~ (DSPI_CTAR_FMSZ(0x0F)));
                dspi_ptr->CTAR[0] |= DSPI_CTAR_FMSZ(*param_ptr - 1);
                /* Enable SPI module */
                dspi_ptr->MCR &= (~ DSPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_GET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                *param_ptr = DSPI_PUSHR_PCS(io_info_ptr->CS);
            }
            break;
        case IO_IOCTL_SPI_SET_CS:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                io_info_ptr->CS = DSPI_PUSHR_PCS_GET(*param_ptr);
            }
            break;
        case IO_IOCTL_SPI_ENABLE_MODF:
            result = MQX_IO_OPERATION_NOT_AVAILABLE;
            break;
        case IO_IOCTL_SPI_DISABLE_MODF:
            break;
        case IO_IOCTL_SPI_SET_CS_CALLBACK:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                callbacks = (SPI_CS_CALLBACK_STRUCT_PTR)(param_ptr);
                for (num = 0; num < DSPI_CS_COUNT; num++)
                {
                    if (0 != (callbacks->MASK & (DSPI_PUSHR_PCS(1 << num))))
                    {
                        io_info_ptr->CS_CALLBACK[num] = callbacks->CALLBACK;
                        io_info_ptr->CS_USERDATA[num] = callbacks->USERDATA;
                    }
                }
            }
            break;
        case IO_IOCTL_SPI_READ_WRITE:
            if (NULL == param_ptr)
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            }
            else
            {
                rw_ptr = (SPI_READ_WRITE_STRUCT_PTR)param_ptr;
                _dspi_polled_tx_rx (io_info_ptr, (uint_8_ptr)(rw_ptr->WRITE_BUFFER), (uint_8_ptr)(rw_ptr->READ_BUFFER), rw_ptr->BUFFER_LENGTH);
            }
            break;
        case IO_IOCTL_SPI_KEEP_QSPI_CS_ACTIVE:
            result = MQX_IO_OPERATION_NOT_AVAILABLE;
            break;
        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }
    return result;
}
コード例 #2
0
ファイル: spi_pol_dspi.c プロジェクト: mihaSoro/MQX-3.7.0
/*FUNCTION****************************************************************
* 
* Function Name    : _dspi_polled_ioctl
* Returned Value   : MQX error code
* Comments         : 
*    This function performs miscellaneous services for
*    the SPI I/O device.  
*
*END*********************************************************************/
uint_32 _dspi_polled_ioctl
    (
        /* [IN] The address of the device specific information */
        DSPI_INFO_STRUCT_PTR         io_info_ptr,
        
        /* [IN] The command to perform */
        uint_32                      cmd,
        
        /* [IN] Parameters for the command */
        uint_32_ptr                  param_ptr,
        
        /* [IN] Opening flags */
        uint_32                      flags
    )
{
    SPI_MemMapPtr                    dspi_ptr;
    SPI_CS_CALLBACK_STRUCT_PTR       callbacks;
    uint_32                          val, num, size, command;
    uint_32                          result = SPI_OK;
    SPI_READ_WRITE_STRUCT_PTR        rw_ptr;
    uchar_ptr                        input, output;
    
    dspi_ptr = io_info_ptr->DSPI_PTR;
    
    switch (cmd) 
    {
        case IO_IOCTL_SPI_GET_BAUD:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                val = dspi_ptr->CTAR[0];
                val = BAUDRATE_PRESCALER[SPI_CTAR_PBR_GET(val)] * BAUDRATE_SCALER[SPI_CTAR_BR_GET(val)];
                *param_ptr = (uint_32)((io_info_ptr->INIT.CLOCK_SPEED) / val);
            }
            break;
        case IO_IOCTL_SPI_SET_BAUD:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else if (0 == (*param_ptr)) 
            {
                result = SPI_ERROR_BAUD_RATE_INVALID;
            } 
            else 
            {
                val = _dspi_find_baudrate (io_info_ptr->INIT.CLOCK_SPEED, *param_ptr);
                /* Disable SPI module */
                dspi_ptr->MCR |= SPI_MCR_HALT_MASK;
                /* Set the frequency divider */
                dspi_ptr->CTAR[0] &= (~ (SPI_CTAR_PBR(0x0F) | SPI_CTAR_BR(0x0F)));
                dspi_ptr->CTAR[0] |= val;
                /* Enable SPI module */
                dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_DEVICE_DISABLE:
            dspi_ptr->MCR |= SPI_MCR_HALT_MASK;
            break;
        case IO_IOCTL_SPI_DEVICE_ENABLE:
            dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK);
            break;
        case IO_IOCTL_SPI_GET_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {
                if (dspi_ptr->CTAR[0] & SPI_CTAR_CPOL_MASK)
                {
                    if (dspi_ptr->CTAR[0] & SPI_CTAR_CPHA_MASK)
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE3;
                    }
                    else
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE2;
                    }
                }
                else
                {
                    if (dspi_ptr->CTAR[0] & SPI_CTAR_CPHA_MASK)
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE1;
                    }
                    else
                    {
                        *param_ptr = SPI_CLK_POL_PHA_MODE0;
                    }
                }
            }
            break;
        case IO_IOCTL_SPI_SET_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {       
                /* Disable SPI module */
                dspi_ptr->MCR |= SPI_MCR_HALT_MASK;
                switch (*param_ptr)
                {
                    case (SPI_CLK_POL_PHA_MODE0):
                        /* Inactive state of SPI_CLK = logic 0 */
                        dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPOL_MASK);
                        /* SPI_CLK transitions middle of bit timing */
                        dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPHA_MASK);
                        break;
                    case (SPI_CLK_POL_PHA_MODE1):
                        /* Inactive state of SPI_CLK = logic 0 */
                        dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPOL_MASK);
                        /* SPI_CLK transitions begining of bit timing */
                        dspi_ptr->CTAR[0] |= SPI_CTAR_CPHA_MASK;
                        break;
                    case (SPI_CLK_POL_PHA_MODE2):
                        /* Inactive state of SPI_CLK = logic 1 */
                        dspi_ptr->CTAR[0] |= SPI_CTAR_CPOL_MASK;
                        /* SPI_CLK transitions middle of bit timing */
                        dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPHA_MASK);
                        break;
                    case (SPI_CLK_POL_PHA_MODE3):
                        /* Inactive state of SPI_CLK = logic 1 */
                        dspi_ptr->CTAR[0] |= SPI_CTAR_CPOL_MASK;
                        /* SPI_CLK transitions begining of bit timing */
                        dspi_ptr->CTAR[0] |= SPI_CTAR_CPHA_MASK;
                        break;
                    default:
                        result = SPI_ERROR_MODE_INVALID;
                        break;
                }
                /* Enable SPI module */
                dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_GET_TRANSFER_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {
                if (dspi_ptr->MCR & SPI_MCR_MSTR_MASK) 
                {
                    *param_ptr = SPI_DEVICE_MASTER_MODE;
                }
                else 
                {
                    *param_ptr = SPI_DEVICE_SLAVE_MODE;
                }
            }
            break;
        case IO_IOCTL_SPI_SET_TRANSFER_MODE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else
            {
                /* Disable SPI module */
                dspi_ptr->MCR |= SPI_MCR_HALT_MASK;
                /* Set transfer mode */
                if (*param_ptr == SPI_DEVICE_SLAVE_MODE)
                {
                    dspi_ptr->MCR &= (~ SPI_MCR_MSTR_MASK);
                }
                else if (*param_ptr == SPI_DEVICE_MASTER_MODE)
                {
                    dspi_ptr->MCR |= SPI_MCR_MSTR_MASK;
                }
                else
                {
                    result = SPI_ERROR_TRANSFER_MODE_INVALID;
                }
                /* Enable SPI module */
                dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_GET_ENDIAN:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else if (dspi_ptr->CTAR[0] & SPI_CTAR_LSBFE_MASK)
            {
                *param_ptr = SPI_DEVICE_LITTLE_ENDIAN;   
            }
            else
            {
                *param_ptr = SPI_DEVICE_BIG_ENDIAN; 
            }
            break;
        case IO_IOCTL_SPI_SET_ENDIAN:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else if (! (dspi_ptr->MCR & SPI_MCR_MSTR_MASK)) 
            {
                result = SPI_ERROR_ENDIAN_INVALID;
            }
            else if (*param_ptr == SPI_DEVICE_LITTLE_ENDIAN)
            {
                dspi_ptr->CTAR[0] |= SPI_CTAR_LSBFE_MASK;
            }
            else if (*param_ptr == SPI_DEVICE_BIG_ENDIAN)
            {
                dspi_ptr->CTAR[0] &= (~ SPI_CTAR_LSBFE_MASK);
            }
            else
            {
                result = SPI_ERROR_ENDIAN_INVALID;
            }
            break;
        case IO_IOCTL_SPI_GET_STATS:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                *((SPI_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATS;
            }
            break;
        case IO_IOCTL_SPI_CLEAR_STATS:
            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;
            break;
        case IO_IOCTL_FLUSH_OUTPUT:
        case IO_IOCTL_SPI_FLUSH_DEASSERT_CS:
            while ((0 != io_info_ptr->RECEIVING) || (0 != io_info_ptr->ONTHEWAY) || (dspi_ptr->RSER & SPI_RSER_TFFF_RE_MASK)) 
               {};  // waiting for completion
            if ((0 == (flags & SPI_FLAG_NO_DEASSERT_ON_FLUSH)) || (IO_IOCTL_SPI_FLUSH_DEASSERT_CS == cmd))
            {
                /* Deassert all chip selects */
                if (dspi_ptr->MCR & SPI_MCR_MSTR_MASK) 
                {
                    for (num = 0; num < DSPI_CS_COUNT; num++)
                    {
                        if ((NULL != io_info_ptr->CS_CALLBACK[num]) && (0 != (io_info_ptr->CS_ACTIVE & (1 << num))))
                        {
                            io_info_ptr->CS_CALLBACK[num] (SPI_PUSHR_PCS(1 << num), 1, io_info_ptr->CS_USERDATA[num]);
                        }                
                    }
                    io_info_ptr->CS_ACTIVE = 0;
                    dspi_ptr->RSER &= (~ SPI_RSER_RFDF_RE_MASK);
                    val = (uint_32)-1;
                    _dspi_polled_tx_rx (io_info_ptr, (uchar_ptr)&val, TRUE, 0);
                    dspi_ptr->RSER |= SPI_RSER_RFDF_RE_MASK;
                }
            }
            break;
        case IO_IOCTL_SPI_GET_FRAMESIZE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                *param_ptr = SPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) + 1;
            }
            break;
        case IO_IOCTL_SPI_SET_FRAMESIZE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                /* Disable SPI module */
                dspi_ptr->MCR |= SPI_MCR_HALT_MASK;
                dspi_ptr->CTAR[0] &= (~ (SPI_CTAR_FMSZ(0x0F)));
                dspi_ptr->CTAR[0] |= SPI_CTAR_FMSZ(*param_ptr - 1);
                /* Enable SPI module */
                dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK);
            }
            break;
        case IO_IOCTL_SPI_GET_CS:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                *param_ptr = SPI_PUSHR_PCS(io_info_ptr->CS);
            }
            break;
        case IO_IOCTL_SPI_SET_CS:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                io_info_ptr->CS = SPI_PUSHR_PCS_GET(*param_ptr);
            }
            break;
        case IO_IOCTL_SPI_ENABLE_MODF:
            result = MQX_IO_OPERATION_NOT_AVAILABLE;
            break;
        case IO_IOCTL_SPI_DISABLE_MODF:
            break;
        case IO_IOCTL_SPI_SET_CS_CALLBACK:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                callbacks = (SPI_CS_CALLBACK_STRUCT_PTR)(param_ptr);
                for (num = 0; num < DSPI_CS_COUNT; num++)
                {
                    if (0 != (callbacks->MASK & (SPI_PUSHR_PCS(1 << num))))
                    {
                        io_info_ptr->CS_CALLBACK[num] = callbacks->CALLBACK;
                        io_info_ptr->CS_USERDATA[num] = callbacks->USERDATA;
                    }                
                }
            }
            break;
        case IO_IOCTL_SPI_READ_WRITE:
            if (NULL == param_ptr) 
            {
                result = SPI_ERROR_INVALID_PARAMETER;
            } 
            else 
            {
                rw_ptr = (SPI_READ_WRITE_STRUCT_PTR)param_ptr;
                command = SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(io_info_ptr->CS);
                size = rw_ptr->BUFFER_LENGTH;
                input = (uchar_ptr)rw_ptr->WRITE_BUFFER;
                output = (uchar_ptr)rw_ptr->READ_BUFFER;
                for (num = 0; num < size; num++)
                {
                    val = _dspi_polled_tx_rx (io_info_ptr, input, TRUE, command);
                    if (SPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) > 7)
                    {
                        output[0] = (uint_8)(val >> 8);
                        output++;
                        input++;
                    }
                    output[0] = (uint_8)val;
                    output++;
                    input++;
                    io_info_ptr->STATS.RX_PACKETS++;
                    io_info_ptr->STATS.TX_PACKETS++;
                }
            }
            break;
        case IO_IOCTL_SPI_KEEP_QSPI_CS_ACTIVE:
            result = MQX_IO_OPERATION_NOT_AVAILABLE;
            break;
        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }