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