Exemplo n.º 1
0
/*!
 * \brief Set period of hwtimer.
 *
 * The function provides an alternate way to setup the timer to desired period specified in microseconds rather than to frequency in Hz.
 * The function gets the value of the base frequency of the timer via clock manager, calculates required divider ratio and calls low layer driver to setup the timer accordingly.
 * Call to this function might be expensive as it may require complex calculation to choose the best configuration of dividers.
 * The actual complexity depends on timer module implementation.
 * If there is only single divider or counter preload value (typical case) then there is no significant overhead.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 * \param clock_id[in]  Clock identifier used for obtaining timer's source clock.
 * \param period[in]    Required period of timer in micro seconds.
 *
 * \return MQX_OK or an error code Returned from low level SETDIV function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers.
 * \return MQX_INVALID_POINTER     When low level SETDIV function point to NULL.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
_mqx_int hwtimer_set_period(HWTIMER_PTR hwtimer, uint32_t clock_id, uint32_t period)
{
    uint32_t clock_freq;
    uint64_t divider;
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif) || (0 == period))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->SET_DIV)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    /* Store clock_id in struct*/
    hwtimer->clock_id = clock_id;
    /* Find out input frequency*/
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)clock_id);
    divider = (((uint64_t)clock_freq * period)) / 1000000 ;
    /* If Reqired frequency is higher than input clock frequency, we set divider 1 (for setting highest possible frequency)*/
    if (0 == divider)
    {
        divider = 1;
    }
    /* if divider is greater than 32b value we set divider to max 32b value*/
    else if (divider & 0xFFFFFFFF00000000)
    {
        divider = 0xFFFFFFFF;
    }
    return hwtimer->devif->SET_DIV(hwtimer, (uint32_t)divider);
}
Exemplo n.º 2
0
/*!
 * \brief The function configures timer to tick at frequency as close as possible to the requested one.
 *
 * Actual accuracy depends on the timer module.
 * The function gets the value of the base frequency of the timer via clock manager, calculates required divider ratio and calls low layer driver to setup the timer accordingly.
 * Call to this function might be expensive as it may require complex calculation to choose the best configuration of dividers. The actual complexity depends on timer module implementation.
 * If there is only single divider or counter preload value (typical case) then there is no significant overhead.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 * \param clock_id[in]  Clock identifier used for obtaining timer's source clock.
 * \param freq[in]      Required frequency of timer in Hz.
 *
 * \return MQX_OK or an error code Returned from low level SETDIV function.
 * \return MQX_INVALID_PARAMETER   When input parameter hwtimer or his device structure are NULL pointers.
 * \return MQX_INVALID_POINTER     When low level SETDIV function point to NULL.
 *
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
_mqx_int hwtimer_set_freq(HWTIMER_PTR hwtimer, uint32_t clock_id, uint32_t freq)
{
    uint32_t clock_freq;
    uint32_t divider;
    #if MQX_CHECK_ERRORS
    if ((NULL == hwtimer) || (NULL == hwtimer->devif) || (0 == freq))
    {
        return MQX_INVALID_PARAMETER;
    }
    if (NULL == hwtimer->devif->SET_DIV)
    {
        return MQX_INVALID_POINTER;
    }
    #endif
    /* Store clock_id in struct*/
    hwtimer->clock_id = clock_id;
    /* Find out input frequency*/
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)clock_id);
    divider = clock_freq / freq;
    /* If Reqired frequency is higher than input clock frequency, we set divider 1 (for setting highest possible frequency)*/
    if (0 == divider)
    {
        divider = 1;
    }
    return hwtimer->devif->SET_DIV(hwtimer, divider);
}
Exemplo n.º 3
0
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_dma_ioctl
* Returned Value   : MQX error code
* Comments         :
*    This function performs miscellaneous services for
*    the SPI I/O device.
*
*END*********************************************************************/
static _mqx_int _dspi_dma_ioctl
    (
        /* [IN] The address of the device specific information */
        void                          *io_info_ptr,

        /* [IN] SPI transfer parameters */
        SPI_PARAM_STRUCT_PTR           params,

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

        /* [IN] Parameters for the command */
        uint32_t                    *param_ptr
    )
{
    DSPI_DMA_INFO_STRUCT_PTR           dspi_info_ptr = (DSPI_DMA_INFO_STRUCT_PTR)io_info_ptr;
    uint32_t                            result = SPI_OK;

    BSP_CLOCK_CONFIGURATION clock_config;
    uint32_t clock_speed;

    switch (cmd)
    {
        case IO_IOCTL_SPI_GET_BAUD:
            clock_config = _bsp_get_clock_configuration();
            clock_speed = _bsp_get_clock(clock_config, dspi_info_ptr->CLOCK_SOURCE);
            *((uint32_t *)param_ptr) = _dspi_find_baudrate(clock_speed, *((uint32_t *)param_ptr), NULL);
            break;

        default:
            result = IO_ERROR_INVALID_IOCTL_CMD;
            break;
    }
    return result;
}
Exemplo n.º 4
0
/*!
 * \brief Get period of hwtimer.
 *
 * The function returns current period of the timer in microseconds calculated from the base frequency and actual divider settings of the timer.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 *
 * \return period       Already set period of hwtimer.
 * \return 0            Input parameter hwtimer is NULL pointer.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_get_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
uint32_t hwtimer_get_period(HWTIMER_PTR hwtimer)
{
    uint32_t clock_freq;
    uint32_t period;
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return 0;   //MQX_INVALID_PARAMETER;
    }
    #endif
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)hwtimer->clock_id);
    /* The result is always less than UINT32_MAX */
    period = ((uint64_t)1000000 * hwtimer->divider) / clock_freq;
    return period;
}
Exemplo n.º 5
0
/*!
 * \brief Get frequency of hwtimer.
 *
 * The function returns current frequency of the timer calculated from the base frequency and actual divider settings of the timer or zero in case of an error.
 *
 * \param hwtimer[in]   Pointer to hwtimer structure.
 *
 * \return frequency    Already set frequency of hwtimer
 * \return 0            When input parameter hwtimer is NULL pointer or his divider member is zero.
 *
 * \see hwtimer_set_freq
 * \see hwtimer_set_period
 * \see hwtimer_get_period
 * \see hwtimer_get_modulo
 * \see hwtimer_get_time
 * \see hwtimer_get_ticks
 */
uint32_t hwtimer_get_freq(HWTIMER_PTR hwtimer)
{
    uint32_t clock_freq;
    #if MQX_CHECK_ERRORS
    if (NULL == hwtimer)
    {
        return 0;   //MQX_INVALID_PARAMETER;
    }
    /* Uninitialized hwtimer contains value of 0 for divider*/
    if (0 == hwtimer->divider)
    {
        return 0;   //MQX_INVALID_POINTER
    }
    #endif
    clock_freq = _bsp_get_clock(_bsp_get_clock_configuration(), (CM_CLOCK_SOURCE)hwtimer->clock_id);
    return clock_freq / hwtimer->divider;
}
Exemplo n.º 6
0
uint_32 _bsp_get_lpt_clock_frequency
    (
        /* [IN] LPT index */
        uint_8  dev_num,
        
        /* [IN} LPT clock source index */
        uint_32 source
    )
{
    if (source < ELEMENTS_OF(lpt_clock_source)) 
    {
        if (CM_CLOCK_SOURCES != lpt_clock_source[source])
        {
            return _bsp_get_clock (_bsp_get_clock_configuration (), lpt_clock_source[source]);
        }
        else
        {
            return 1000;
        }
    }
    return 0;
}
Exemplo n.º 7
0
/*FUNCTION****************************************************************
*
* Function Name    : _dspi_setparam
* Returned Value   :
* Comments         :
*    Set parameters for following transfers.
*
*END*********************************************************************/
static _mqx_int _dspi_setparam
   (
        /* [IN] Device specific context structure */
        void                          *io_info_ptr,

        /* [IN] Parameters to set */
        SPI_PARAM_STRUCT_PTR           params
   )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr;
    VDSPI_REG_STRUCT_PTR               dspi_ptr = dspi_info_ptr->DSPI_PTR;

    BSP_CLOCK_CONFIGURATION clock_config;
    uint32_t clock_speed;

    uint32_t ctar;
    uint32_t cpol_invert;

    /* Transfer mode */
    if ((params->ATTR & SPI_ATTR_TRANSFER_MODE_MASK) != SPI_ATTR_MASTER_MODE)
        return SPI_ERROR_TRANSFER_MODE_INVALID;

    /* Set master mode */
    dspi_ptr->MCR |= DSPI_MCR_MSTR_MASK;

    clock_config = _bsp_get_clock_configuration();

    /* Check the parameter against most recent values to avoid time consuming baudrate finding routine */
    if ((dspi_info_ptr->CLOCK_CONFIG != clock_config) || (dspi_info_ptr->BAUDRATE != params->BAUDRATE))
    {
        dspi_info_ptr->CLOCK_CONFIG = clock_config;
        dspi_info_ptr->BAUDRATE = params->BAUDRATE;

        /* Find configuration of prescalers best matching the desired value */
        clock_speed = _bsp_get_clock(dspi_info_ptr->CLOCK_CONFIG, dspi_info_ptr->CLOCK_SOURCE);
        _dspi_find_baudrate(clock_speed, dspi_info_ptr->BAUDRATE, &(dspi_info_ptr->CTAR_TIMING));
    }

    /* Set up prescalers */
    ctar = dspi_info_ptr->CTAR_TIMING;

    /* Set up transfer parameters */
    _dspi_ctar_params(params, &ctar);

    /* Check whether it is necessary to invert idle clock polarity */
    cpol_invert = (dspi_ptr->CTAR[0] ^ ctar) & DSPI_CTAR_CPOL_MASK;

    /* Store to register */
    dspi_ptr->CTAR[0] = ctar;

    dspi_info_ptr->DUMMY_PATTERN = params->DUMMY_PATTERN;
    dspi_info_ptr->ATTR = params->ATTR;

    if (cpol_invert) {
        /* Dummy transfer with inactive CS to invert idle clock polarity */
        dspi_ptr->MCR = (dspi_ptr->MCR & ~(uint32_t)DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(0xFF);
        _dspi_tx_rx(io_info_ptr, NULL, NULL, (params->FRAMESIZE+7)/8);
    }

    /* Set CS signals */
    //dspi_ptr->MCR = (dspi_ptr->MCR & ~DSPI_MCR_PCSIS_MASK) | DSPI_MCR_PCSIS(~(params->CS));

    return SPI_OK;
}