示例#1
0
文件: tc.c 项目: wugsh/wgs
/**
 * \brief Find best MCK divisor
 *
 * Finds the best MCK divisor given the timer frequency and MCK. The result
 * is guaranteed to satisfy the following equation:
 * \code
 *   (MCK / (DIV * 65536)) <= freq <= (MCK / DIV)
 * \endcode
 * with DIV being the highest possible value.
 *
 * \param freq  Desired timer freq.
 * \param div  Divisor value.
 * \param tc_clks  TCCLKS field value for divisor.
 *
 * \return 1 if a proper divisor has been found, otherwise 0.
 */
uint32_t tc_find_mck_divisor (uint32_t freq, uint32_t * div,
				  uint32_t * tc_clks)
{
	const uint32_t periph_clock = pmc_get_peripheral_clock(ID_TC0);
	const uint32_t available_freqs[5] = {periph_clock >> 1, periph_clock >> 3, periph_clock >> 5, periph_clock >> 7, 32768};

	int i = 0;
	for (i = 0; i < 5; ++i)
	{
		uint32_t tmp = freq << 1;
		if (tmp > available_freqs[i])
			break;
	}

	i = (i == 5 ? i-1 : i);

	/*  Store results */
	if (div) {
		*div = periph_clock / available_freqs[i];
	}
	if (tc_clks) {
		*tc_clks = i;
	}

	return 1;
}
示例#2
0
static bool _gmac_configure_mdc_clock(Gmac *gmac)
{
	uint32_t mck, clk;

	mck = pmc_get_peripheral_clock(get_gmac_id_from_addr(gmac));

	/* Disable RX/TX */
	gmac->GMAC_NCR &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);

	/* Find divider */
	if (mck <= 20000000) {
		clk = GMAC_NCFGR_CLK_MCK_8; // MCK/8
	} else if (mck <= 40000000) {
		clk = GMAC_NCFGR_CLK_MCK_16; // MCK/16
	} else if (mck <= 80000000) {
		clk = GMAC_NCFGR_CLK_MCK_32; // MCK/32
	} else if (mck <= 120000000) {
		clk = GMAC_NCFGR_CLK_MCK_48; // MCK/48
	} else if (mck <= 160000000) {
		clk = GMAC_NCFGR_CLK_MCK_64; // MCK/64
	} else if (mck <= 240000000) {
		clk = GMAC_NCFGR_CLK_MCK_96; // MCK/96
	} else {
		trace_error("MCK too high, cannot configure MDC clock.\r\n");
		return false;
	}

	/* configure MDC clock divider and enable RX/TX */
	gmac->GMAC_NCFGR = (gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | clk;
	gmac->GMAC_NCR |= (GMAC_NCR_RXEN | GMAC_NCR_TXEN);

	return true;
}
示例#3
0
文件: tc.c 项目: wugsh/wgs
void tc_trigger_on_freq(Tc* tc, uint32_t channel_num, uint32_t freq)
{
	uint32_t div = 0;
	uint32_t tcclks = 0;
	uint32_t tc_id = get_tc_id_from_addr(tc);
	TcChannel* channel = &tc->TC_CHANNEL[channel_num];

	tc_find_mck_divisor(freq, &div, &tcclks);
	tc_configure(tc, channel_num, tcclks | TC_CMR_CPCTRG);
	channel->TC_RC = (pmc_get_peripheral_clock(tc_id) / div) / freq;
}
示例#4
0
文件: uart.c 项目: wugsh/wgs
/*
 * Initializes the UART with the given parameters, and enables both the
 * transmitter and the receiver. The mode parameter contains the value of the
 * UART_MR register.
 * Value UART_STANDARD can be used for mode to get the most common configuration
 * (i.e. aysnchronous, 8bits, no parity, 1 stop bit, no flow control).
 * \param mode  Operating mode to configure.
 * \param baudrate  Desired baudrate (e.g. 115200).
 * \param mck  Frequency of the system master clock in Hz.
 */
void uart_configure(Uart* pUart, uint32_t mode, uint32_t baudrate)
{
	uint32_t uart_id = get_uart_id_from_addr(pUart);
	// Reset & disable receiver and transmitter, disable interrupts
	pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS
		| UART_CR_RSTSTA;
	pUart->UART_IDR = 0xFFFFFFFF;
	// Configure baud rate
	pUart->UART_BRGR = pmc_get_peripheral_clock(uart_id) / (baudrate * 16);
	// Configure mode register
	pUart->UART_MR = mode;
	// Enable receiver and transmitter
	pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
}
示例#5
0
/**
 * \brief Configures an DBGU peripheral with the specified parameters.
 *
 * \param dgbu  Pointer to the DBGU peripheral to configure
 * \param baudrate  Baudrate at which the DBGU should operate (in Hz).
 * \param clock  Frequency of the system master clock (in Hz).
 */
void dbgu_configure(Dbgu* dbgu, uint32_t mode, uint32_t baudrate)
{
	assert(dbgu == DBGU);

	/* Reset and disable receiver & transmitter */
	dbgu->DBGU_CR = DBGU_CR_RSTRX | DBGU_CR_RSTTX;
	dbgu->DBGU_IDR = 0xFFFFFFFF;
	dbgu->DBGU_SR;

	/* Configure mode */
	dbgu->DBGU_MR = mode;

	/* Configure baudrate */
	dbgu->DBGU_BRGR = ROUND_INT_DIV(pmc_get_peripheral_clock(ID_DBGU) / 16, baudrate);

	/* Enable receiver and transmitter */
	dbgu->DBGU_CR = DBGU_CR_RXEN | DBGU_CR_TXEN;
}
示例#6
0
uint32_t qspi_set_baudrate(Qspi *qspi, uint32_t baudrate)
{
	uint32_t mck, scr, scbr;

	if (!baudrate)
		return 0;

	/* Serial Clock Baudrate */
	mck = pmc_get_peripheral_clock(get_qspi_id_from_addr(qspi));
	scbr = (mck + baudrate - 1) / baudrate;
	if (scbr > 0)
		scbr--;

	/* Update the Serial Clock Register */
	scr = qspi->QSPI_SCR;
	scr &= ~QSPI_SCR_SCBR_Msk;
	scr |= QSPI_SCR_SCBR(scbr);
	qspi->QSPI_SCR = scr;

	return mck / (scbr + 1);
}
示例#7
0
/**
 * \brief Configures a SSC peripheral.If the divided clock is not used, the master
 * clock frequency can be set to 0.
 * \note The emitter and transmitter are disabled by this function.
 * \param ssc  Pointer to an SSC instance.
 * \param bitRate  bit rate.
 * \param masterClock  master clock.
 */
void
SSC_Configure(Ssc * ssc, uint32_t bitRate, uint32_t masterClock)
{
	uint32_t id;
	uint32_t clock;
	id = (ssc == SSC0) ? ID_SSC0 : ID_SSC1;
	clock = pmc_get_peripheral_clock(id);

	/* Reset, disable receiver & transmitter */
	ssc->SSC_CR = SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST;

	/* Configure clock frequency */
	if (bitRate != 0) {

		ssc->SSC_CMR = clock / (2 * bitRate);
	} else {

		ssc->SSC_CMR = 0;
	}
	/* Enable SSC peripheral clock */
	//pmc_enable_peripheral(id);
}