/*! * \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); }
/*! * \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); }
/*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; }
/*! * \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; }
/*! * \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; }
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; }
/*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; }