/**
 * \file
 *
 * \brief SAM D20 SERCOM USART Driver
 *
 * Copyright (C) 2012-2013 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \asf_license_stop
 *
 */
#include "usart.h"
#include <pinmux.h>
#if USART_CALLBACK_MODE == true
#  include "usart_interrupt.h"
#endif

/**
 * \internal Checks a USART config against current set config
 *
 * This function will check that the config does not alter the
 * configuration of the module. If the new config changes any
 * setting, the initialization will be discarded.
 *
 * \param[in]  module  Pointer to the software instance struct
 * \param[in]  config  Pointer to the configuration struct
 *
 * \return The status of the configuration
 * \retval STATUS_ERR_INVALID_ARG       If invalid argument(s) were provided.
 * \retval STATUS_ERR_DENIED            If configuration was different from previous
 * \retval STATUS_OK                    If the configuration was written
 */
static enum status_code _usart_check_config(
		struct usart_module *const module,
		const struct usart_config *const config)
{
		/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	SercomUsart *const usart_hw = &(module->hw->USART);
	Sercom *const hw = (module->hw);

	uint32_t pad0 = config->pinmux_pad0;
	uint32_t pad1 = config->pinmux_pad1;
	uint32_t pad2 = config->pinmux_pad2;
	uint32_t pad3 = config->pinmux_pad3;

	/* SERCOM PAD0 */
	if (pad0 == PINMUX_DEFAULT) {
		pad0 = _sercom_get_default_pad(hw, 0);
	}
	if ((pad0 != PINMUX_UNUSED) && ((pad0 & 0xFFFF)!=
			system_pinmux_pin_get_mux_position(pad0 >> 16))) {
		return STATUS_ERR_DENIED;
	}

	/* SERCOM PAD1 */
	if (pad1 == PINMUX_DEFAULT) {
		pad1 = _sercom_get_default_pad(hw, 1);
	}
	if ((pad1 != PINMUX_UNUSED) && ((pad1 & 0xFFFF) !=
			system_pinmux_pin_get_mux_position(pad1 >> 16))) {
		return STATUS_ERR_DENIED;
	}

	/* SERCOM PAD2 */
	if (pad2 == PINMUX_DEFAULT) {
		pad2 = _sercom_get_default_pad(hw, 2);
	}
	if ((pad2 != PINMUX_UNUSED) && ((pad2 & 0xFFFF) !=
			system_pinmux_pin_get_mux_position(pad2 >> 16))) {
		return STATUS_ERR_DENIED;
	}

	/* SERCOM PAD3 */
	if (pad3 == PINMUX_DEFAULT) {
		pad3 = _sercom_get_default_pad(hw, 3);
	}
	if ((pad3 != PINMUX_UNUSED) && ((pad3 & 0xFFFF) !=
			system_pinmux_pin_get_mux_position(pad3 >> 16))) {
		return STATUS_ERR_DENIED;
	}

	/* Find baud value and compare it */
	uint16_t baud  = 0;
	enum status_code status_code = STATUS_OK;

	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(SERCOM_GCLK_ID), &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);
		} else {
			status_code =
					_sercom_get_async_baud_val(config->baudrate,
						system_gclk_chan_get_hz(SERCOM_GCLK_ID), &baud);
		}

		break;
	}

	if (status_code != STATUS_OK) {
		/* Baud rate calculation error, return status code */
		return STATUS_ERR_DENIED;
	}

	if (usart_hw->BAUD.reg != baud) {
		return STATUS_ERR_DENIED;
	}

	uint32_t ctrla = 0;
	uint32_t ctrlb = 0;

	/* Check sample mode, data order, internal muxing, and clock polarity */
	ctrla = (uint32_t)config->data_order |
		(uint32_t)config->mux_setting |
		(uint32_t)config->transfer_mode |
		SERCOM_USART_CTRLA_MODE(0) |
		(config->clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos);

	/* set enable bit */
	ctrla |= (SERCOM_USART_CTRLA_ENABLE);

	if (config->use_external_clock == false) {
		ctrla |= SERCOM_USART_CTRLA_MODE_USART_INT_CLK;
	}
	else {
		ctrla |= SERCOM_USART_CTRLA_MODE_USART_EXT_CLK;
	}

	/* Check stopbits and character size */
	ctrlb = (uint32_t)config->stopbits | (uint32_t)config->character_size |
			(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) {
		ctrla |= SERCOM_USART_CTRLA_FORM(1);
		ctrlb |= config->parity;
	} else {
		ctrla |= SERCOM_USART_CTRLA_FORM(0);
	}

	if (usart_hw->CTRLA.reg == ctrla && usart_hw->CTRLB.reg == ctrlb) {
		module->character_size = config->character_size;
		return STATUS_OK;
	} else {
		module->hw = NULL;
		return STATUS_ERR_DENIED;
	}
}

/**
 * \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;

	/* Set data order, internal muxing, and clock polarity */
	ctrla = (uint32_t)config->data_order |
		(uint32_t)config->mux_setting |
		(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);
			} else {
				status_code =
						_sercom_get_async_baud_val(config->baudrate,
							system_gclk_chan_get_hz(gclk_index), &baud);
			}

			break;
	}

	/* Check if calculating the baud rate failed */
	if (status_code != STATUS_OK) {
		/* Abort */
		return status_code;
	}

	/* 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_USART_INT_CLK;
	}
	else {
		ctrla |= SERCOM_USART_CTRLA_MODE_USART_EXT_CLK;
	}

	/* Set stopbits, character size and enable transceivers */
	ctrlb = (uint32_t)config->stopbits | (uint32_t)config->character_size |
			(config->receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) |
			(config->transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos);

	/* Set parity mode */
	if (config->parity != USART_PARITY_NONE) {
		ctrla |= SERCOM_USART_CTRLA_FORM(1);
		ctrlb |= config->parity;
	} else {
		ctrla |= SERCOM_USART_CTRLA_FORM(0);
	}

	/* Set run mode during device sleep */
	if (config->run_in_standby) {
		/* Enable in sleep mode */
		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;
}

/**
 * \brief Initializes the device
 *
 * Initializes the USART device based on the setting specified in the
 * configuration struct.
 *
 * \param[out] module  Pointer to USART device
 * \param[in]  hw      Pointer to USART hardware instance
 * \param[in]  config  Pointer to configuration struct
 *
 * \return Status of the initialization
 *
 * \retval STATUS_OK                       The initialization was successful
 * \retval STATUS_BUSY                     The USART module is busy
 *                                         resetting
 * \retval STATUS_ERR_DENIED               The USART have not been disabled in
 *                                         advance of initialization
 * \retval STATUS_ERR_INVALID_ARG          The configuration struct contains
 *                                         invalid configuration
 * \retval STATUS_ERR_ALREADY_INITIALIZED  The SERCOM instance has already been
 *                                         initialized with different clock
 *                                         configuration
 * \retval STATUS_ERR_BAUD_UNAVAILABLE     The BAUD rate given by the
 *                                         configuration
 *                                         struct cannot be reached with
 *                                         the current clock configuration
 */
enum status_code usart_init(
		struct usart_module *const module,
		Sercom *const hw,
		const struct usart_config *const config)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(hw);
	Assert(config);

	enum status_code status_code = STATUS_OK;

	/* Assign module pointer to software instance struct */
	module->hw = hw;

	/* Get a pointer to the hardware module instance */
	SercomUsart *const usart_hw = &(module->hw->USART);

	uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
	uint32_t pm_index     = sercom_index + PM_APBCMASK_SERCOM0_Pos;
	uint32_t gclk_index   = sercom_index + SERCOM0_GCLK_ID_CORE;

	if (usart_hw->CTRLA.reg & SERCOM_USART_CTRLA_SWRST) {
		/* The module is busy resetting itself */
		return STATUS_BUSY;
	}

	if (usart_hw->CTRLA.reg & SERCOM_USART_CTRLA_ENABLE) {
		/* Check if the new setting are the same as the old */
		return _usart_check_config(module, config);
	}

	/* Turn on module in PM */
	system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);

	/* Set up the GCLK for the module */
	struct system_gclk_chan_config gclk_chan_conf;
	system_gclk_chan_get_config_defaults(&gclk_chan_conf);
	gclk_chan_conf.source_generator = config->generator_source;
	system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
	system_gclk_chan_enable(gclk_index);
	sercom_set_gclk_generator(config->generator_source, false);

	/* Set character size */
	module->character_size = config->character_size;

	/* Set transmitter and receiver status */
	module->receiver_enabled = config->receiver_enable;
	module->transmitter_enabled = config->transmitter_enable;

	/* Configure Pins */
	struct system_pinmux_config pin_conf;
	system_pinmux_get_config_defaults(&pin_conf);
	pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;

	/* Set configuration according to the config struct */
	status_code = _usart_set_config(module, config);
	if(status_code != STATUS_OK) {
		return status_code;
	}

	uint32_t pad0 = config->pinmux_pad0;
	uint32_t pad1 = config->pinmux_pad1;
	uint32_t pad2 = config->pinmux_pad2;
	uint32_t pad3 = config->pinmux_pad3;

	/* SERCOM PAD0 */
	if (pad0 == PINMUX_DEFAULT) {
		pad0 = _sercom_get_default_pad(hw, 0);
	}
	if (pad0 != PINMUX_UNUSED) {
		pin_conf.mux_position = pad0 & 0xFFFF;
		system_pinmux_pin_set_config(pad0 >> 16, &pin_conf);
	}

	/* SERCOM PAD1 */
	if (pad1 == PINMUX_DEFAULT) {
		pad1 = _sercom_get_default_pad(hw, 1);
	}
	if (pad1 != PINMUX_UNUSED) {
		pin_conf.mux_position = pad1 & 0xFFFF;
		system_pinmux_pin_set_config(pad1 >> 16, &pin_conf);
	}

	/* SERCOM PAD2 */
	if (pad2 == PINMUX_DEFAULT) {
		pad2 = _sercom_get_default_pad(hw, 2);
	}
	if (pad2 != PINMUX_UNUSED) {
		pin_conf.mux_position = pad2 & 0xFFFF;
		system_pinmux_pin_set_config(pad2 >> 16, &pin_conf);
	}

	/* SERCOM PAD3 */
	if (pad3 == PINMUX_DEFAULT) {
		pad3 = _sercom_get_default_pad(hw, 3);
	}
	if (pad3 != PINMUX_UNUSED) {
		pin_conf.mux_position = pad3 & 0xFFFF;
		system_pinmux_pin_set_config(pad3 >> 16, &pin_conf);
	}
#if USART_CALLBACK_MODE == true
	/* Initialize parameters */
	for (uint32_t i = 0; i < USART_CALLBACK_N; i++) {
		module->callback[i]            = NULL;
	}

	module->tx_buffer_ptr              = NULL;
	module->rx_buffer_ptr              = NULL;
	module->remaining_tx_buffer_length = 0x0000;
	module->remaining_rx_buffer_length = 0x0000;
	module->callback_reg_mask          = 0x00;
	module->callback_enable_mask       = 0x00;
	module->rx_status                  = STATUS_OK;
	module->tx_status                  = STATUS_OK;

	/* Set interrupt handler and register USART software module struct in
	 * look-up table */
	uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw);
	_sercom_set_handler(instance_index, _usart_interrupt_handler);
	_sercom_instances[instance_index] = module;
#endif
	return status_code;
}

/**
 * \brief Transmit a character via the USART
 *
 * This blocking function will transmit a single character via the
 * USART.
 *
 * \param[in]  module   Pointer to the software instance struct
 * \param[in]  tx_data  Data to transfer
 *
 * \return Status of the operation
 * \retval STATUS_OK         If the operation was completed
 * \retval STATUS_BUSY       If the operation was not completed, due to the USART
 *                           module being busy.
 * \retval STATUS_ERR_DENIED If the transmitter is not enabled
 */
enum status_code usart_write_wait(
		struct usart_module *const module,
		const uint16_t tx_data)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	/* Get a pointer to the hardware module instance */
	SercomUsart *const usart_hw = &(module->hw->USART);

	/* Check that the transmitter is enabled */
	if (!(module->transmitter_enabled)) {
		return STATUS_ERR_DENIED;
	}

#if USART_CALLBACK_MODE == true
	/* Check if the USART is busy doing asynchronous operation. */
	if (module->remaining_tx_buffer_length > 0) {
		return STATUS_BUSY;
	}

#else
	/* Check if USART is ready for new data */
	if (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) {
		/* Return error code */
		return STATUS_BUSY;
	}
#endif

	/* Wait until synchronization is complete */
	_usart_wait_for_sync(module);

	/* Write data to USART module */
	usart_hw->DATA.reg = tx_data;

	while (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC)) {
		/* Wait until data is sent */
	}

	return STATUS_OK;
}

/**
 * \brief Receive a character via the USART
 *
 * This blocking function will receive a character via the USART.
 *
 * \param[in]   module   Pointer to the software instance struct
 * \param[out]  rx_data  Pointer to received data
 *
 * \return Status of the operation
 * \retval STATUS_OK                If the operation was completed
 * \retval STATUS_BUSY              If the operation was not completed,
 *                                  due to the USART module being busy
 * \retval STATUS_ERR_BAD_FORMAT    If the operation was not completed,
 *                                  due to configuration mismatch between USART
 *                                  and the sender
 * \retval STATUS_ERR_BAD_OVERFLOW  If the operation was not completed,
 *                                  due to the baud rate being too low or the
 *                                  system frequency being too high
 * \retval STATUS_ERR_BAD_DATA      If the operation was not completed, due to
 *                                  data being corrupted
 * \retval STATUS_ERR_DENIED        If the receiver is not enabled
 */
enum status_code usart_read_wait(
		struct usart_module *const module,
		uint16_t *const rx_data)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	/* Error variable */
	uint8_t error_code;

	/* Get a pointer to the hardware module instance */
	SercomUsart *const usart_hw = &(module->hw->USART);

	/* Check that the receiver is enabled */
	if (!(module->receiver_enabled)) {
		return STATUS_ERR_DENIED;
	}

#if USART_CALLBACK_MODE == true
	/* Check if the USART is busy doing asynchronous operation. */
	if (module->remaining_rx_buffer_length > 0) {
		return STATUS_BUSY;
	}

#else
	/* Check if USART has new data */
	if (!(usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC)) {
		/* Return error code */
		return STATUS_BUSY;
	}
#endif

	/* Wait until synchronization is complete */
	_usart_wait_for_sync(module);

	/* Read out the status code and mask away all but the 3 LSBs*/
	error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK);

	/* Check if an error has occurred during the receiving */
	if (error_code) {
		/* Check which error occurred */
		if (error_code & SERCOM_USART_STATUS_FERR) {
			/* Clear flag by writing a 1 to it and
			 * return with an error code */
			usart_hw->STATUS.reg = SERCOM_USART_STATUS_FERR;

			return STATUS_ERR_BAD_FORMAT;
		} else if (error_code & SERCOM_USART_STATUS_BUFOVF) {
			/* Clear flag by writing a 1 to it and
			 * return with an error code */
			usart_hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF;

			return STATUS_ERR_OVERFLOW;
		} else if (error_code & SERCOM_USART_STATUS_PERR) {
			/* Clear flag by writing a 1 to it and
			 * return with an error code */
			usart_hw->STATUS.reg = SERCOM_USART_STATUS_PERR;

			return STATUS_ERR_BAD_DATA;
		}
	}

	/* Read data from USART module */
	*rx_data = usart_hw->DATA.reg;

	return STATUS_OK;
}

/**
 * \brief Transmit a buffer of characters via the USART
 *
 * This blocking function will transmit a block of \c length characters
 * via the USART
 *
 * \note Using this function in combination with the interrupt (\c _job) functions is
 *       not recommended as it has no functionality to check if there is an
 *       ongoing interrupt driven operation running or not.
 *
 * \param[in]  module   Pointer to USART software instance struct
 * \param[in]  tx_data  Pointer to data to transmit
 * \param[in]  length   Number of characters to transmit
 *
 * \return Status of the operation
 * \retval STATUS_OK              If operation was completed
 * \retval STATUS_ERR_INVALID_ARG If operation was not completed, due to invalid
 *                                arguments
 * \retval STATUS_ERR_TIMEOUT     If operation was not completed, due to USART
 *                                module timing out
 * \retval STATUS_ERR_DENIED      If the transmitter is not enabled
 */
enum status_code usart_write_buffer_wait(
		struct usart_module *const module,
		const uint8_t *tx_data,
		uint16_t length)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	/* Check if the buffer length is valid */
	if (length == 0) {
		return STATUS_ERR_INVALID_ARG;
	}

	/* Check that the transmitter is enabled */
	if (!(module->transmitter_enabled)) {
		return STATUS_ERR_DENIED;
	}

	/* Get a pointer to the hardware module instance */
	SercomUsart *const usart_hw = &(module->hw->USART);

	/* Wait until synchronization is complete */
	_usart_wait_for_sync(module);

	uint16_t tx_pos = 0;

	/* Blocks while buffer is being transferred */
	while (length--) {
		/* Wait for the USART to be ready for new data and abort
		* operation if it doesn't get ready within the timeout*/
		for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
			if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) {
				break;
			} else if (i == USART_TIMEOUT) {
				return STATUS_ERR_TIMEOUT;
			}
		}

		/* Data to send is at least 8 bits long */
		uint16_t data_to_send = tx_data[tx_pos++];

		/* Check if the character size exceeds 8 bit */
		if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
			data_to_send |= (tx_data[tx_pos++] << 8);
		}

		/* Send the data through the USART module */
		usart_write_wait(module, data_to_send);
	}

	/* Wait until Transmit is complete or timeout */
	for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
		if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) {
			break;
		} else if (i == USART_TIMEOUT) {
			return STATUS_ERR_TIMEOUT;
		}
	}

	return STATUS_OK;
}

/**
 * \brief Receive a buffer of \c length characters via the USART
 *
 * This blocking function will receive a block of \c length characters
 * via the USART.
 *
 * \note Using this function in combination with the interrupt (\c *_job)
 *       functions is not recommended as it has no functionality to check if
 *       there is an ongoing interrupt driven operation running or not.
 *
 * \param[in]  module   Pointer to USART software instance struct
 * \param[out] rx_data  Pointer to receive buffer
 * \param[in]  length   Number of characters to receive
 *
 * \return Status of the operation.
 * \retval STATUS_OK                If operation was completed
 * \retval STATUS_ERR_INVALID_ARG   If operation was not completed, due to an
 *                                  invalid argument being supplied
 * \retval STATUS_ERR_TIMEOUT       If operation was not completed, due
 *                                  to USART module timing out
 * \retval STATUS_ERR_BAD_FORMAT    If the operation was not completed,
 *                                  due to a configuration mismatch
 *                                  between USART and the sender
 * \retval STATUS_ERR_BAD_OVERFLOW  If the operation was not completed,
 *                                  due to the baud rate being too low or the
 *                                  system frequency being too high
 * \retval STATUS_ERR_BAD_DATA      If the operation was not completed, due
 *                                  to data being corrupted
 * \retval STATUS_ERR_DENIED        If the receiver is not enabled
 */
enum status_code usart_read_buffer_wait(
		struct usart_module *const module,
		uint8_t *rx_data,
		uint16_t length)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	/* Check if the buffer length is valid */
	if (length == 0) {
		return STATUS_ERR_INVALID_ARG;
	}

	/* Check that the receiver is enabled */
	if (!(module->receiver_enabled)) {
		return STATUS_ERR_DENIED;
	}

	/* Get a pointer to the hardware module instance */
	SercomUsart *const usart_hw = &(module->hw->USART);

	uint16_t rx_pos = 0;

	/* Blocks while buffer is being received */
	while (length--) {
		/* Wait for the USART to have new data and abort operation if it
		 * doesn't get ready within the timeout*/
		for (uint32_t i = 0; i <= USART_TIMEOUT; i++) {
			if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) {
				break;
			} else if (i == USART_TIMEOUT) {
				return STATUS_ERR_TIMEOUT;
			}
		}

		enum status_code retval;
		uint16_t received_data = 0;

		retval = usart_read_wait(module, &received_data);

		if (retval != STATUS_OK) {
			/* Overflow, abort */
			return retval;
		}

		/* Read value will be at least 8-bits long */
		rx_data[rx_pos++] = received_data;

		/* If 9-bit data, write next received byte to the buffer */
		if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
			rx_data[rx_pos++] = (received_data >> 8);
		}
	}

	return STATUS_OK;
}
