コード例 #1
0
ファイル: main.c プロジェクト: ataradov/mcu-starter-projects
//-----------------------------------------------------------------------------
static void uart_init(uint32_t baud)
{
  HAL_GPIO_UART_TX_out();
  HAL_GPIO_UART_TX_pmuxen(HAL_GPIO_PMUX_D);
  HAL_GPIO_UART_RX_in();
  HAL_GPIO_UART_RX_pmuxen(HAL_GPIO_PMUX_D);

  MCLK->APBBMASK.reg |= MCLK_APBBMASK_SERCOM2;

  GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
  while (0 == (GCLK->PCHCTRL[SERCOM2_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN));

  SERCOM2->USART.CTRLA.reg =
      SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*INT_CLK*/) |
      SERCOM_USART_CTRLA_RXPO(1/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(0/*PAD0*/) |
      SERCOM_USART_CTRLA_SAMPR(1);

  SERCOM2->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
      SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

  #define BAUD_VAL (F_CPU / (16 * baud))
  #define FP_VAL   ((F_CPU / baud - 16 * BAUD_VAL) / 2)

  SERCOM2->USART.BAUD.reg = 
      SERCOM_USART_BAUD_FRACFP_BAUD(BAUD_VAL) |
      SERCOM_USART_BAUD_FRACFP_FP(FP_VAL);

  SERCOM2->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}
コード例 #2
0
ファイル: SERCOM.cpp プロジェクト: agdl/ArduinoCore-samd
/* 	=========================
 *	===== Sercom UART
 *	=========================
*/
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
{
  initClockNVIC();
  resetUART();

  //Setting the CTRLA register
  sercom->USART.CTRLA.reg =	SERCOM_USART_CTRLA_MODE(mode) |
                SERCOM_USART_CTRLA_SAMPR(sampleRate);

  //Setting the Interrupt register
  sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_RXC |  //Received complete
                                SERCOM_USART_INTENSET_ERROR; //All others errors

  if ( mode == UART_INT_CLOCK )
  {
    uint16_t sampleRateValue;

    if (sampleRate == SAMPLE_RATE_x16) {
      sampleRateValue = 16;
    } else {
      sampleRateValue = 8;
    }

    // Asynchronous fractional mode (Table 24-2 in datasheet)
    //   BAUD = fref / (sampleRateValue * fbaud)
    // (multiply by 8, to calculate fractional piece)
    uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate);

    sercom->USART.BAUD.FRAC.FP   = (baudTimes8 % 8);
    sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8);
  }
}
コード例 #3
0
ファイル: main.c プロジェクト: ataradov/mcu-starter-projects
//-----------------------------------------------------------------------------
static void uart_init(uint32_t baud)
{
  uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU;

  HAL_GPIO_UART_TX_out();
  HAL_GPIO_UART_TX_pmuxen(HAL_GPIO_PMUX_D);
  HAL_GPIO_UART_RX_in();
  HAL_GPIO_UART_RX_pmuxen(HAL_GPIO_PMUX_D);

  MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM4;

  GCLK->PCHCTRL[SERCOM4_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
  while (0 == (GCLK->PCHCTRL[SERCOM4_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN));

  SERCOM4->USART.CTRLA.reg =
      SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*USART_INT_CLK*/) |
      SERCOM_USART_CTRLA_RXPO(3/*PAD3*/) | SERCOM_USART_CTRLA_TXPO(1/*PAD2*/);

  SERCOM4->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
      SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

  SERCOM4->USART.BAUD.reg = (uint16_t)br;

  SERCOM4->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}
コード例 #4
0
ファイル: uart.c プロジェクト: daniel-k/RIOT
int uart_init_blocking(uart_t uart, uint32_t baudrate)
{
    /* Calculate the BAUD value */
    uint64_t temp1 = ((16 * ((uint64_t)baudrate)) << 32);
    uint64_t ratio = _long_division(temp1 , UART_0_REF_F);
    uint64_t scale = ((uint64_t)1 << 32) - ratio;
    uint64_t baud_calculated = (65536 * scale) >> 32;

    switch (uart) {
#if UART_0_EN
        case UART_0:
            /* Enable the peripheral channel */
            GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg |= GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0;

            while (!(GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN)) {
                /* Wait for clock synchronization */
            }

            MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3;
            /* configure PINS to input/output*/
            UART_0_PORT.DIRSET.reg = (1 << UART_0_TX_PIN);  /* tx's direction is output */
            UART_0_PORT.PINCFG[UART_0_RX_PIN % 32].bit.INEN = true; /* buffer rx pin's value */

            /* enable PMUX for pins and set to config C. */
            UART_0_PORT.WRCONFIG.reg = PORT_WRCONFIG_WRPINCFG \
                                        | PORT_WRCONFIG_WRPMUX \
                                        | PORT_WRCONFIG_PMUX(0x2) \
                                        | PORT_WRCONFIG_PMUXEN \
                                        | UART_0_PINS;

            UART_0_DEV.CTRLA.bit.ENABLE = 0; //Disable to write, need to sync tho
            while(UART_0_DEV.SYNCBUSY.bit.ENABLE);

            /* set to LSB, asynchronous mode without parity, PAD0 Tx, PAD1 Rx,
             * 16x over-sampling, internal clk */
            UART_0_DEV.CTRLA.reg = SERCOM_USART_CTRLA_DORD \
                                    | SERCOM_USART_CTRLA_FORM(0x0) \
                                    | SERCOM_USART_CTRLA_SAMPA(0x0) \
                                    | SERCOM_USART_CTRLA_TXPO(0x0) \
                                    | SERCOM_USART_CTRLA_RXPO(0x1) \
                                    | SERCOM_USART_CTRLA_SAMPR(0x0) \
                                    | SERCOM_USART_CTRLA_MODE(0x1) \
                                    | (UART_0_RUNSTDBY ? SERCOM_USART_CTRLA_RUNSTDBY : 0);

            /* Set baud rate */
            UART_0_DEV.BAUD.bit.BAUD = baud_calculated;

            /* enable receiver and transmitter, one stop bit*/
            UART_0_DEV.CTRLB.reg = (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);
            while(UART_0_DEV.SYNCBUSY.bit.CTRLB);

            break;
#endif
    }

    uart_poweron(uart);
    return 0;
}
コード例 #5
0
/* 	=========================
 *	===== Sercom UART
 *	=========================
*/
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
{
#if (SAML21)
  // On the SAML21, SERCOM5 is on PD0, which is a low power domain on a different bridge than the other SERCOMs.
  // SERCOM5 does not support SAMPLE_RATE_x8 or SAMPLE_RATE_x3.
  if (sercom == SERCOM5) {
    sampleRate = SAMPLE_RATE_x16;
  }
#endif

  initClockNVIC();
  resetUART();

  //Setting the CTRLA register
  sercom->USART.CTRLA.reg =	SERCOM_USART_CTRLA_MODE(mode) |
                SERCOM_USART_CTRLA_SAMPR(sampleRate);

  //Setting the Interrupt register
  sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_RXC |  //Received complete
                                SERCOM_USART_INTENSET_ERROR; //All others errors

  if ( mode == UART_INT_CLOCK )
  {
    uint16_t sampleRateValue;

    if (sampleRate == SAMPLE_RATE_x16) {
      sampleRateValue = 16;
    } else {
      sampleRateValue = 8;
    }

#if 0
    // Asynchronous arithmetic mode
    // 65535 * ( 1 - sampleRateValue * baudrate / SercomClock);
    // 65535 - 65535 * (sampleRateValue * baudrate / SercomClock));
    // sercom->USART.BAUD.reg = 65535.0f * ( 1.0f - (float)(sampleRateValue) * (float)(baudrate) / (float)(SercomCoreClock));  // this pulls in 3KB of floating point math code
    // make numerator much larger than denominator so result is integer (avoid floating point).
    uint64_t numerator = ((sampleRateValue * (uint64_t)baudrate) << 32); // 32 bits of shifting ensures no loss of precision.
    uint64_t ratio = divide64(numerator, SercomClock);
    uint64_t scale = ((uint64_t)1 << 32) - ratio;
    uint64_t baudValue = (65536 * scale) >> 32;
    sercom->USART.BAUD.reg = baudValue;
#endif
    // Asynchronous fractional mode (Table 24-2 in datasheet)
    //   BAUD = fref / (sampleRateValue * fbaud)
    // (multiply by 8, to calculate fractional piece)
    uint32_t baudTimes8 = (SercomClock * 8) / (sampleRateValue * baudrate);

    sercom->USART.BAUD.FRAC.FP   = (baudTimes8 % 8);
    sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8);
  }
コード例 #6
0
/* 	=========================
 *	===== Sercom UART
 *	=========================
*/
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
{
    initClockNVIC();
    resetUART();

    //Setting the CTRLA register
    sercom->USART.CTRLA.reg =	SERCOM_USART_CTRLA_MODE(mode) |
                                SERCOM_USART_CTRLA_SAMPR(sampleRate);

    //Setting the Interrupt register
    sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_RXC |  //Received complete
                                    SERCOM_USART_INTENSET_ERROR; //All others errors

    if ( mode == UART_INT_CLOCK )
    {
        uint16_t sampleRateValue ;

        if ( sampleRate == SAMPLE_RATE_x16 )
        {
            sampleRateValue = 16 ;
        }
        else
        {
            if ( sampleRate == SAMPLE_RATE_x8 )
            {
                sampleRateValue = 8 ;
            }
            else
            {
                sampleRateValue = 3 ;
            }
        }

        // Asynchronous arithmetic mode
        // 65535 * ( 1 - sampleRateValue * baudrate / SystemCoreClock);
        // 65535 - 65535 * (sampleRateValue * baudrate / SystemCoreClock));
        sercom->USART.BAUD.reg = 65535.0f * ( 1.0f - (float)(sampleRateValue) * (float)(baudrate) / (float)(SystemCoreClock));
    }
}
コード例 #7
0
ファイル: usart.c プロジェクト: Wiredhome/mbed
/**
 * \internal
 * Set Configuration of the USART module
 */
static enum status_code _usart_set_config(
    struct usart_module *const module,
    const struct usart_config *const config)
{
    /* Sanity check arguments */
    Assert(module);
    Assert(module->hw);

    /* Get a pointer to the hardware module instance */
    SercomUsart *const usart_hw = &(module->hw->USART);

    /* Index for generic clock */
    uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
    uint32_t gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;

    /* Cache new register values to minimize the number of register writes */
    uint32_t ctrla = 0;
    uint32_t ctrlb = 0;
    uint16_t baud  = 0;

    enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
    enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;

#ifdef FEATURE_USART_OVER_SAMPLE
    switch (config->sample_rate) {
        case USART_SAMPLE_RATE_16X_ARITHMETIC:
            mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
            sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
            break;
        case USART_SAMPLE_RATE_8X_ARITHMETIC:
            mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
            sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
            break;
        case USART_SAMPLE_RATE_3X_ARITHMETIC:
            mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
            sample_num = SERCOM_ASYNC_SAMPLE_NUM_3;
            break;
        case USART_SAMPLE_RATE_16X_FRACTIONAL:
            mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
            sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
            break;
        case USART_SAMPLE_RATE_8X_FRACTIONAL:
            mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
            sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
            break;
    }
#endif

    /* Set data order, internal muxing, and clock polarity */
    ctrla = (uint32_t)config->data_order |
            (uint32_t)config->mux_setting |
#ifdef FEATURE_USART_OVER_SAMPLE
            config->sample_adjustment |
            config->sample_rate |
#endif
#ifdef FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION
            (config->immediate_buffer_overflow_notification << SERCOM_USART_CTRLA_IBON_Pos) |
#endif
            (config->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);

    enum status_code status_code = STATUS_OK;

    /* Get baud value from mode and clock */
    switch (config->transfer_mode) {
        case USART_TRANSFER_SYNCHRONOUSLY:
            if (!config->use_external_clock) {
                status_code = _sercom_get_sync_baud_val(config->baudrate,
                                                        system_gclk_chan_get_hz(gclk_index), &baud);
            }

            break;

        case USART_TRANSFER_ASYNCHRONOUSLY:
            if (config->use_external_clock) {
                status_code =
                    _sercom_get_async_baud_val(config->baudrate,
                                               config->ext_clock_freq, &baud, mode, sample_num);
            } else {
                status_code =
                    _sercom_get_async_baud_val(config->baudrate,
                                               system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
            }

            break;
    }

    /* Check if calculating the baudrate failed */
    if (status_code != STATUS_OK) {
        /* Abort */
        return status_code;
    }

#ifdef FEATURE_USART_IRDA
    if(config->encoding_format_enable) {
        usart_hw->RXPL.reg = config->receive_pulse_length;
    }
#endif

    /* Wait until synchronization is complete */
    _usart_wait_for_sync(module);

    /*Set baud val */
    usart_hw->BAUD.reg = baud;

    /* Set sample mode */
    ctrla |= config->transfer_mode;

    if (config->use_external_clock == false) {
        ctrla |= SERCOM_USART_CTRLA_MODE(0x1);
    } else {
        ctrla |= SERCOM_USART_CTRLA_MODE(0x0);
    }

    /* Set stopbits, character size and enable transceivers */
    ctrlb = (uint32_t)config->stopbits | (uint32_t)config->character_size |
#ifdef FEATURE_USART_IRDA
            (config->encoding_format_enable << SERCOM_USART_CTRLB_ENC_Pos) |
#endif
#ifdef FEATURE_USART_START_FRAME_DECTION
            (config->start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) |
#endif
#ifdef FEATURE_USART_COLLISION_DECTION
            (config->collision_detection_enable << SERCOM_USART_CTRLB_COLDEN_Pos) |
#endif
            (config->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
            (config->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);

    /* Check parity mode bits */
    if (config->parity != USART_PARITY_NONE) {
#ifdef FEATURE_USART_LIN_SLAVE
        if(config->lin_slave_enable) {
            ctrla |= SERCOM_USART_CTRLA_FORM(0x5);
        } else {
            ctrla |= SERCOM_USART_CTRLA_FORM(1);
        }
#else
        ctrla |= SERCOM_USART_CTRLA_FORM(1);
#endif
        ctrlb |= config->parity;
    } else {
#ifdef FEATURE_USART_LIN_SLAVE
        if(config->lin_slave_enable) {
            ctrla |= SERCOM_USART_CTRLA_FORM(0x4);
        } else {
            ctrla |= SERCOM_USART_CTRLA_FORM(0);
        }
#else
        ctrla |= SERCOM_USART_CTRLA_FORM(0);
#endif
    }

    /* Set whether module should run in standby. */
    if (config->run_in_standby || system_is_debugger_present()) {
        ctrla |= SERCOM_USART_CTRLA_RUNSTDBY;
    }

    /* Wait until synchronization is complete */
    _usart_wait_for_sync(module);

    /* Write configuration to CTRLB */
    usart_hw->CTRLB.reg = ctrlb;

    /* Wait until synchronization is complete */
    _usart_wait_for_sync(module);

    /* Write configuration to CTRLA */
    usart_hw->CTRLA.reg = ctrla;

    return STATUS_OK;
}
コード例 #8
0
ファイル: usart.c プロジェクト: BrownCubeSat/EQUiSat
/**
 * \internal
 * Set Configuration of the USART module
 */
static enum status_code _usart_set_config(
		struct usart_module *const module,
		const struct usart_config *const config)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	/* Get a pointer to the hardware module instance */
	SercomUsart *const usart_hw = &(module->hw->USART);

	/* Index for generic clock */
	uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
	uint32_t gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;

	/* Cache new register values to minimize the number of register writes */
	uint32_t ctrla = 0;
	uint32_t ctrlb = 0;
#ifdef FEATURE_USART_ISO7816
	uint32_t ctrlc = 0;
#endif
	uint16_t baud  = 0;
	uint32_t transfer_mode;

	enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
	enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;

#ifdef FEATURE_USART_OVER_SAMPLE
	switch (config->sample_rate) {
		case USART_SAMPLE_RATE_16X_ARITHMETIC:
			mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
			sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
			break;
		case USART_SAMPLE_RATE_8X_ARITHMETIC:
			mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
			sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
			break;
		case USART_SAMPLE_RATE_3X_ARITHMETIC:
			mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
			sample_num = SERCOM_ASYNC_SAMPLE_NUM_3;
			break;
		case USART_SAMPLE_RATE_16X_FRACTIONAL:
			mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
			sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
			break;
		case USART_SAMPLE_RATE_8X_FRACTIONAL:
			mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL;
			sample_num = SERCOM_ASYNC_SAMPLE_NUM_8;
			break;
	}
#endif

	/* Set data order, internal muxing, and clock polarity */
	ctrla = (uint32_t)config->data_order |
		(uint32_t)config->mux_setting |
	#ifdef FEATURE_USART_OVER_SAMPLE
		config->sample_adjustment |
		config->sample_rate |
	#endif
	#ifdef FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION
		(config->immediate_buffer_overflow_notification << SERCOM_USART_CTRLA_IBON_Pos) |
	#endif
		(config->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);

	enum status_code status_code = STATUS_OK;

	transfer_mode = (uint32_t)config->transfer_mode;
#ifdef FEATURE_USART_ISO7816
	if(config->iso7816_config.enabled) {
		transfer_mode = config->iso7816_config.protocol_t;
	}
#endif
	/* Get baud value from mode and clock */
#ifdef FEATURE_USART_ISO7816
	if(config->iso7816_config.enabled) {
		baud = config->baudrate;
	} else {
#endif
	switch (transfer_mode)
	{
		case USART_TRANSFER_SYNCHRONOUSLY:
			if (!config->use_external_clock) {
				status_code = _sercom_get_sync_baud_val(config->baudrate,
						system_gclk_chan_get_hz(gclk_index), &baud);
			}

			break;

		case USART_TRANSFER_ASYNCHRONOUSLY:
			if (config->use_external_clock) {
				status_code =
						_sercom_get_async_baud_val(config->baudrate,
							config->ext_clock_freq, &baud, mode, sample_num);
			} else {
				status_code =
						_sercom_get_async_baud_val(config->baudrate,
							system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
			}

			break;
	}

	/* Check if calculating the baudrate failed */
	if (status_code != STATUS_OK) {
		/* Abort */
		return status_code;
	}
#ifdef FEATURE_USART_ISO7816
	}
#endif

#ifdef FEATURE_USART_IRDA
	if(config->encoding_format_enable) {
		usart_hw->RXPL.reg = config->receive_pulse_length;
	}
#endif

	/* Wait until synchronization is complete */
	_usart_wait_for_sync(module);

	/*Set baud val */
	usart_hw->BAUD.reg = baud;

	/* Set sample mode */
	ctrla |= transfer_mode;

	if (config->use_external_clock == false) {
		ctrla |= SERCOM_USART_CTRLA_MODE(0x1);
	}
	else {
		ctrla |= SERCOM_USART_CTRLA_MODE(0x0);
	}

	/* Set stopbits and enable transceivers */
	ctrlb =  
		#ifdef FEATURE_USART_IRDA
			(config->encoding_format_enable << SERCOM_USART_CTRLB_ENC_Pos) |
		#endif
		#ifdef FEATURE_USART_START_FRAME_DECTION
			(config->start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) |
		#endif
		#ifdef FEATURE_USART_COLLISION_DECTION
			(config->collision_detection_enable << SERCOM_USART_CTRLB_COLDEN_Pos) |
		#endif
			(config->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
			(config->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);

#ifdef FEATURE_USART_ISO7816
	if(config->iso7816_config.enabled) {
		ctrla |= SERCOM_USART_CTRLA_FORM(0x07);
		if (config->iso7816_config.enable_inverse) {
			ctrla |= SERCOM_USART_CTRLA_TXINV | SERCOM_USART_CTRLA_RXINV;
		}
		ctrlb |=  USART_CHARACTER_SIZE_8BIT;
		
		switch(config->iso7816_config.protocol_t) {
			case ISO7816_PROTOCOL_T_0:
				ctrlb |= (uint32_t)config->stopbits;	
				ctrlc |= SERCOM_USART_CTRLC_GTIME(config->iso7816_config.guard_time) | \
						(config->iso7816_config.inhibit_nack) | \
						(config->iso7816_config.successive_recv_nack) | \
						SERCOM_USART_CTRLC_MAXITER(config->iso7816_config.max_iterations);
				break;	
			case ISO7816_PROTOCOL_T_1:
				ctrlb |= USART_STOPBITS_1;
				break;		
		}
	} else {
#endif
	ctrlb |= (uint32_t)config->character_size;
	/* Check parity mode bits */
	if (config->parity != USART_PARITY_NONE) {
		ctrla |= SERCOM_USART_CTRLA_FORM(1);
		ctrlb |= config->parity;
	} else {
#ifdef FEATURE_USART_LIN_SLAVE
		if(config->lin_slave_enable) {
			ctrla |= SERCOM_USART_CTRLA_FORM(0x4);
		} else {
			ctrla |= SERCOM_USART_CTRLA_FORM(0);
		}
#else
		ctrla |= SERCOM_USART_CTRLA_FORM(0);
#endif
	}
#ifdef FEATURE_USART_ISO7816
	}
#endif

#ifdef FEATURE_USART_LIN_MASTER
	usart_hw->CTRLC.reg = ((usart_hw->CTRLC.reg) & SERCOM_USART_CTRLC_GTIME_Msk)
						| config->lin_header_delay
						| config->lin_break_length;

	if (config->lin_node != LIN_INVALID_MODE) {
		ctrla &= ~(SERCOM_USART_CTRLA_FORM(0xf));
		ctrla |= config->lin_node;
	}
#endif

	/* Set whether module should run in standby. */
	if (config->run_in_standby || system_is_debugger_present()) {
		ctrla |= SERCOM_USART_CTRLA_RUNSTDBY;
	}

	/* Wait until synchronization is complete */
	_usart_wait_for_sync(module);

	/* Write configuration to CTRLB */
	usart_hw->CTRLB.reg = ctrlb;

	/* Wait until synchronization is complete */
	_usart_wait_for_sync(module);

	/* Write configuration to CTRLA */
	usart_hw->CTRLA.reg = ctrla;

#ifdef FEATURE_USART_RS485
	if ((usart_hw->CTRLA.reg & SERCOM_USART_CTRLA_FORM_Msk) != \
		SERCOM_USART_CTRLA_FORM(0x07)) {
		usart_hw->CTRLC.reg &= ~(SERCOM_USART_CTRLC_GTIME(0x7));
		usart_hw->CTRLC.reg |= SERCOM_USART_CTRLC_GTIME(config->rs485_guard_time);
	}
#endif

#ifdef FEATURE_USART_ISO7816
	if(config->iso7816_config.enabled) {
		_usart_wait_for_sync(module);
		usart_hw->CTRLC.reg = ctrlc;
	}
#endif

	return STATUS_OK;
}
コード例 #9
0
ファイル: serial_api.c プロジェクト: DanKupiniak/mbed
static enum status_code usart_set_config_default(serial_t *obj)
{
    /* Sanity check arguments */
    MBED_ASSERT(obj);
    /* Index for generic clock */
    uint32_t sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj));
    uint32_t gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;

    /* Cache new register values to minimize the number of register writes */
    uint32_t ctrla = 0;
    uint32_t ctrlb = 0;
    uint16_t baud  = 0;

    enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
    enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;

    /* Set data order, internal muxing, and clock polarity */
    ctrla = (uint32_t)USART_DATAORDER_LSB |         // data order
            (uint32_t)pSERIAL_S(obj)->mux_setting;  // mux setting  // clock polarity is not used


    /* Get baud value from mode and clock */
    _sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);  // for asynchronous transfer mode

    /* Wait until synchronization is complete */
    usart_syncing(obj);

    /*Set baud val */
    _USART(obj).BAUD.reg = baud;

    /* Set sample mode */
    ctrla |= USART_TRANSFER_ASYNCHRONOUSLY;

    /* for disabled external clock source */
    ctrla |= SERCOM_USART_CTRLA_MODE(0x1);

    /* Set stopbits, character size and enable transceivers */
    ctrlb = (uint32_t)pSERIAL_S(obj)->stopbits | (uint32_t)pSERIAL_S(obj)->character_size |
            SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN;  /*transmitter and receiver enable*/
    if (pSERIAL_S(obj)->pins[USART_RX_INDEX] == NC) { /* if pin is NC, have to disable the corresponding transmitter/receiver part */
        ctrlb &= ~SERCOM_USART_CTRLB_RXEN;  /* receiver disable */
    }
    if (pSERIAL_S(obj)->pins[USART_TX_INDEX] == NC) {
        ctrlb &= ~SERCOM_USART_CTRLB_TXEN;  /* transmitter disable  */
    }

    /* Check parity mode bits */
    if (pSERIAL_S(obj)->parity != USART_PARITY_NONE) {
        ctrla |= SERCOM_USART_CTRLA_FORM(1);
        ctrlb |= pSERIAL_S(obj)->parity;
    } else {
        ctrla |= SERCOM_USART_CTRLA_FORM(0);
    }

    /* Wait until synchronization is complete */
    usart_syncing(obj);

    /* Write configuration to CTRLB */
    _USART(obj).CTRLB.reg = ctrlb;

    /* Wait until synchronization is complete */
    usart_syncing(obj);

    /* Write configuration to CTRLA */
    _USART(obj).CTRLA.reg = ctrla;

    return STATUS_OK;
}