mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Wed Nov 04 16:30:11 2015 +0000
Revision:
15:a81a8d6c1dfe
Synchronized with git revision 46af745ef4405614c3fa49abbd9a706a362ea514

Full URL: https://github.com/mbedmicro/mbed/commit/46af745ef4405614c3fa49abbd9a706a362ea514/

Renamed TARGET_SAM_CortexM0+ to TARGET_SAM_CortexM0P for compatiblity with online compiler

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 15:a81a8d6c1dfe 1 /**
mbed_official 15:a81a8d6c1dfe 2 * \file
mbed_official 15:a81a8d6c1dfe 3 *
mbed_official 15:a81a8d6c1dfe 4 * \brief SAM SERCOM USART Asynchronous Driver
mbed_official 15:a81a8d6c1dfe 5 *
mbed_official 15:a81a8d6c1dfe 6 * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved.
mbed_official 15:a81a8d6c1dfe 7 *
mbed_official 15:a81a8d6c1dfe 8 * \asf_license_start
mbed_official 15:a81a8d6c1dfe 9 *
mbed_official 15:a81a8d6c1dfe 10 * \page License
mbed_official 15:a81a8d6c1dfe 11 *
mbed_official 15:a81a8d6c1dfe 12 * Redistribution and use in source and binary forms, with or without
mbed_official 15:a81a8d6c1dfe 13 * modification, are permitted provided that the following conditions are met:
mbed_official 15:a81a8d6c1dfe 14 *
mbed_official 15:a81a8d6c1dfe 15 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 15:a81a8d6c1dfe 16 * this list of conditions and the following disclaimer.
mbed_official 15:a81a8d6c1dfe 17 *
mbed_official 15:a81a8d6c1dfe 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 15:a81a8d6c1dfe 19 * this list of conditions and the following disclaimer in the documentation
mbed_official 15:a81a8d6c1dfe 20 * and/or other materials provided with the distribution.
mbed_official 15:a81a8d6c1dfe 21 *
mbed_official 15:a81a8d6c1dfe 22 * 3. The name of Atmel may not be used to endorse or promote products derived
mbed_official 15:a81a8d6c1dfe 23 * from this software without specific prior written permission.
mbed_official 15:a81a8d6c1dfe 24 *
mbed_official 15:a81a8d6c1dfe 25 * 4. This software may only be redistributed and used in connection with an
mbed_official 15:a81a8d6c1dfe 26 * Atmel microcontroller product.
mbed_official 15:a81a8d6c1dfe 27 *
mbed_official 15:a81a8d6c1dfe 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
mbed_official 15:a81a8d6c1dfe 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 15:a81a8d6c1dfe 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
mbed_official 15:a81a8d6c1dfe 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
mbed_official 15:a81a8d6c1dfe 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mbed_official 15:a81a8d6c1dfe 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
mbed_official 15:a81a8d6c1dfe 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
mbed_official 15:a81a8d6c1dfe 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
mbed_official 15:a81a8d6c1dfe 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
mbed_official 15:a81a8d6c1dfe 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 15:a81a8d6c1dfe 38 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 15:a81a8d6c1dfe 39 *
mbed_official 15:a81a8d6c1dfe 40 * \asf_license_stop
mbed_official 15:a81a8d6c1dfe 41 *
mbed_official 15:a81a8d6c1dfe 42 */
mbed_official 15:a81a8d6c1dfe 43 /*
mbed_official 15:a81a8d6c1dfe 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
mbed_official 15:a81a8d6c1dfe 45 */
mbed_official 15:a81a8d6c1dfe 46
mbed_official 15:a81a8d6c1dfe 47 #include "usart_interrupt.h"
mbed_official 15:a81a8d6c1dfe 48
mbed_official 15:a81a8d6c1dfe 49 /**
mbed_official 15:a81a8d6c1dfe 50 * \internal
mbed_official 15:a81a8d6c1dfe 51 * Asynchronous write of a buffer with a given length
mbed_official 15:a81a8d6c1dfe 52 *
mbed_official 15:a81a8d6c1dfe 53 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 54 * \param[in] tx_data Pointer to data to be transmitted
mbed_official 15:a81a8d6c1dfe 55 * \param[in] length Length of data buffer
mbed_official 15:a81a8d6c1dfe 56 *
mbed_official 15:a81a8d6c1dfe 57 */
mbed_official 15:a81a8d6c1dfe 58 enum status_code _usart_write_buffer(
mbed_official 15:a81a8d6c1dfe 59 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 60 uint8_t *tx_data,
mbed_official 15:a81a8d6c1dfe 61 uint16_t length)
mbed_official 15:a81a8d6c1dfe 62 {
mbed_official 15:a81a8d6c1dfe 63 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 64 Assert(module);
mbed_official 15:a81a8d6c1dfe 65 Assert(module->hw);
mbed_official 15:a81a8d6c1dfe 66 Assert(tx_data);
mbed_official 15:a81a8d6c1dfe 67
mbed_official 15:a81a8d6c1dfe 68 /* Get a pointer to the hardware module instance */
mbed_official 15:a81a8d6c1dfe 69 SercomUsart *const usart_hw = &(module->hw->USART);
mbed_official 15:a81a8d6c1dfe 70
mbed_official 15:a81a8d6c1dfe 71 system_interrupt_enter_critical_section();
mbed_official 15:a81a8d6c1dfe 72
mbed_official 15:a81a8d6c1dfe 73 /* Check if the USART transmitter is busy */
mbed_official 15:a81a8d6c1dfe 74 if (module->remaining_tx_buffer_length > 0) {
mbed_official 15:a81a8d6c1dfe 75 system_interrupt_leave_critical_section();
mbed_official 15:a81a8d6c1dfe 76 return STATUS_BUSY;
mbed_official 15:a81a8d6c1dfe 77 }
mbed_official 15:a81a8d6c1dfe 78
mbed_official 15:a81a8d6c1dfe 79 /* Write parameters to the device instance */
mbed_official 15:a81a8d6c1dfe 80 module->remaining_tx_buffer_length = length;
mbed_official 15:a81a8d6c1dfe 81
mbed_official 15:a81a8d6c1dfe 82 system_interrupt_leave_critical_section();
mbed_official 15:a81a8d6c1dfe 83
mbed_official 15:a81a8d6c1dfe 84 module->tx_buffer_ptr = tx_data;
mbed_official 15:a81a8d6c1dfe 85 module->tx_status = STATUS_BUSY;
mbed_official 15:a81a8d6c1dfe 86
mbed_official 15:a81a8d6c1dfe 87 /* Enable the Data Register Empty Interrupt */
mbed_official 15:a81a8d6c1dfe 88 usart_hw->INTENSET.reg = SERCOM_USART_INTFLAG_DRE;
mbed_official 15:a81a8d6c1dfe 89
mbed_official 15:a81a8d6c1dfe 90 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 91 }
mbed_official 15:a81a8d6c1dfe 92
mbed_official 15:a81a8d6c1dfe 93 /**
mbed_official 15:a81a8d6c1dfe 94 * \internal
mbed_official 15:a81a8d6c1dfe 95 * Asynchronous read of a buffer with a given length
mbed_official 15:a81a8d6c1dfe 96 *
mbed_official 15:a81a8d6c1dfe 97 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 98 * \param[in] rx_data Pointer to data to be received
mbed_official 15:a81a8d6c1dfe 99 * \param[in] length Length of data buffer
mbed_official 15:a81a8d6c1dfe 100 *
mbed_official 15:a81a8d6c1dfe 101 */
mbed_official 15:a81a8d6c1dfe 102 enum status_code _usart_read_buffer(
mbed_official 15:a81a8d6c1dfe 103 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 104 uint8_t *rx_data,
mbed_official 15:a81a8d6c1dfe 105 uint16_t length)
mbed_official 15:a81a8d6c1dfe 106 {
mbed_official 15:a81a8d6c1dfe 107 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 108 Assert(module);
mbed_official 15:a81a8d6c1dfe 109 Assert(module->hw);
mbed_official 15:a81a8d6c1dfe 110 Assert(rx_data);
mbed_official 15:a81a8d6c1dfe 111
mbed_official 15:a81a8d6c1dfe 112 /* Get a pointer to the hardware module instance */
mbed_official 15:a81a8d6c1dfe 113 SercomUsart *const usart_hw = &(module->hw->USART);
mbed_official 15:a81a8d6c1dfe 114
mbed_official 15:a81a8d6c1dfe 115 system_interrupt_enter_critical_section();
mbed_official 15:a81a8d6c1dfe 116
mbed_official 15:a81a8d6c1dfe 117 /* Check if the USART receiver is busy */
mbed_official 15:a81a8d6c1dfe 118 if (module->remaining_rx_buffer_length > 0) {
mbed_official 15:a81a8d6c1dfe 119 system_interrupt_leave_critical_section();
mbed_official 15:a81a8d6c1dfe 120 return STATUS_BUSY;
mbed_official 15:a81a8d6c1dfe 121 }
mbed_official 15:a81a8d6c1dfe 122
mbed_official 15:a81a8d6c1dfe 123 /* Set length for the buffer and the pointer, and let
mbed_official 15:a81a8d6c1dfe 124 * the interrupt handler do the rest */
mbed_official 15:a81a8d6c1dfe 125 module->remaining_rx_buffer_length = length;
mbed_official 15:a81a8d6c1dfe 126
mbed_official 15:a81a8d6c1dfe 127 system_interrupt_leave_critical_section();
mbed_official 15:a81a8d6c1dfe 128
mbed_official 15:a81a8d6c1dfe 129 module->rx_buffer_ptr = rx_data;
mbed_official 15:a81a8d6c1dfe 130 module->rx_status = STATUS_BUSY;
mbed_official 15:a81a8d6c1dfe 131
mbed_official 15:a81a8d6c1dfe 132 /* Enable the RX Complete Interrupt */
mbed_official 15:a81a8d6c1dfe 133 usart_hw->INTENSET.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 15:a81a8d6c1dfe 134
mbed_official 15:a81a8d6c1dfe 135 #ifdef FEATURE_USART_LIN_SLAVE
mbed_official 15:a81a8d6c1dfe 136 /* Enable the break character is received Interrupt */
mbed_official 15:a81a8d6c1dfe 137 if(module->lin_slave_enabled) {
mbed_official 15:a81a8d6c1dfe 138 usart_hw->INTENSET.reg = SERCOM_USART_INTFLAG_RXBRK;
mbed_official 15:a81a8d6c1dfe 139 }
mbed_official 15:a81a8d6c1dfe 140 #endif
mbed_official 15:a81a8d6c1dfe 141
mbed_official 15:a81a8d6c1dfe 142 #ifdef FEATURE_USART_START_FRAME_DECTION
mbed_official 15:a81a8d6c1dfe 143 /* Enable a start condition is detected Interrupt */
mbed_official 15:a81a8d6c1dfe 144 if(module->start_frame_detection_enabled) {
mbed_official 15:a81a8d6c1dfe 145 usart_hw->INTENSET.reg = SERCOM_USART_INTFLAG_RXS;
mbed_official 15:a81a8d6c1dfe 146 }
mbed_official 15:a81a8d6c1dfe 147 #endif
mbed_official 15:a81a8d6c1dfe 148
mbed_official 15:a81a8d6c1dfe 149 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 150 }
mbed_official 15:a81a8d6c1dfe 151
mbed_official 15:a81a8d6c1dfe 152 /**
mbed_official 15:a81a8d6c1dfe 153 * \brief Registers a callback
mbed_official 15:a81a8d6c1dfe 154 *
mbed_official 15:a81a8d6c1dfe 155 * Registers a callback function which is implemented by the user.
mbed_official 15:a81a8d6c1dfe 156 *
mbed_official 15:a81a8d6c1dfe 157 * \note The callback must be enabled by \ref usart_enable_callback,
mbed_official 15:a81a8d6c1dfe 158 * in order for the interrupt handler to call it when the conditions for
mbed_official 15:a81a8d6c1dfe 159 * the callback type are met.
mbed_official 15:a81a8d6c1dfe 160 *
mbed_official 15:a81a8d6c1dfe 161 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 162 * \param[in] callback_func Pointer to callback function
mbed_official 15:a81a8d6c1dfe 163 * \param[in] callback_type Callback type given by an enum
mbed_official 15:a81a8d6c1dfe 164 *
mbed_official 15:a81a8d6c1dfe 165 */
mbed_official 15:a81a8d6c1dfe 166 void usart_register_callback(
mbed_official 15:a81a8d6c1dfe 167 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 168 usart_callback_t callback_func,
mbed_official 15:a81a8d6c1dfe 169 enum usart_callback callback_type)
mbed_official 15:a81a8d6c1dfe 170 {
mbed_official 15:a81a8d6c1dfe 171 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 172 Assert(module);
mbed_official 15:a81a8d6c1dfe 173 Assert(callback_func);
mbed_official 15:a81a8d6c1dfe 174
mbed_official 15:a81a8d6c1dfe 175 /* Register callback function */
mbed_official 15:a81a8d6c1dfe 176 module->callback[callback_type] = callback_func;
mbed_official 15:a81a8d6c1dfe 177
mbed_official 15:a81a8d6c1dfe 178 /* Set the bit corresponding to the callback_type */
mbed_official 15:a81a8d6c1dfe 179 module->callback_reg_mask |= (1 << callback_type);
mbed_official 15:a81a8d6c1dfe 180 }
mbed_official 15:a81a8d6c1dfe 181
mbed_official 15:a81a8d6c1dfe 182 /**
mbed_official 15:a81a8d6c1dfe 183 * \brief Unregisters a callback
mbed_official 15:a81a8d6c1dfe 184 *
mbed_official 15:a81a8d6c1dfe 185 * Unregisters a callback function which is implemented by the user.
mbed_official 15:a81a8d6c1dfe 186 *
mbed_official 15:a81a8d6c1dfe 187 * \param[in,out] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 188 * \param[in] callback_type Callback type given by an enum
mbed_official 15:a81a8d6c1dfe 189 *
mbed_official 15:a81a8d6c1dfe 190 */
mbed_official 15:a81a8d6c1dfe 191 void usart_unregister_callback(
mbed_official 15:a81a8d6c1dfe 192 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 193 enum usart_callback callback_type)
mbed_official 15:a81a8d6c1dfe 194 {
mbed_official 15:a81a8d6c1dfe 195 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 196 Assert(module);
mbed_official 15:a81a8d6c1dfe 197
mbed_official 15:a81a8d6c1dfe 198 /* Unregister callback function */
mbed_official 15:a81a8d6c1dfe 199 module->callback[callback_type] = NULL;
mbed_official 15:a81a8d6c1dfe 200
mbed_official 15:a81a8d6c1dfe 201 /* Clear the bit corresponding to the callback_type */
mbed_official 15:a81a8d6c1dfe 202 module->callback_reg_mask &= ~(1 << callback_type);
mbed_official 15:a81a8d6c1dfe 203 }
mbed_official 15:a81a8d6c1dfe 204
mbed_official 15:a81a8d6c1dfe 205 /**
mbed_official 15:a81a8d6c1dfe 206 * \brief Asynchronous write a data
mbed_official 15:a81a8d6c1dfe 207 *
mbed_official 15:a81a8d6c1dfe 208 * Sets up the driver to write the data given. If registered and enabled,
mbed_official 15:a81a8d6c1dfe 209 * a callback function will be called when the transmit is completed.
mbed_official 15:a81a8d6c1dfe 210 *
mbed_official 15:a81a8d6c1dfe 211 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 212 * \param[in] tx_data Data to transfer
mbed_official 15:a81a8d6c1dfe 213 *
mbed_official 15:a81a8d6c1dfe 214 * \returns Status of the operation.
mbed_official 15:a81a8d6c1dfe 215 * \retval STATUS_OK If operation was completed
mbed_official 15:a81a8d6c1dfe 216 * \retval STATUS_BUSY If operation was not completed, due to the
mbed_official 15:a81a8d6c1dfe 217 * USART module being busy
mbed_official 15:a81a8d6c1dfe 218 * \retval STATUS_ERR_DENIED If the transmitter is not enabled
mbed_official 15:a81a8d6c1dfe 219 */
mbed_official 15:a81a8d6c1dfe 220 enum status_code usart_write_job(
mbed_official 15:a81a8d6c1dfe 221 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 222 const uint16_t *tx_data)
mbed_official 15:a81a8d6c1dfe 223 {
mbed_official 15:a81a8d6c1dfe 224 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 225 Assert(module);
mbed_official 15:a81a8d6c1dfe 226 Assert(tx_data);
mbed_official 15:a81a8d6c1dfe 227
mbed_official 15:a81a8d6c1dfe 228
mbed_official 15:a81a8d6c1dfe 229 /* Check that the transmitter is enabled */
mbed_official 15:a81a8d6c1dfe 230 if (!(module->transmitter_enabled)) {
mbed_official 15:a81a8d6c1dfe 231 return STATUS_ERR_DENIED;
mbed_official 15:a81a8d6c1dfe 232 }
mbed_official 15:a81a8d6c1dfe 233
mbed_official 15:a81a8d6c1dfe 234 /* Call internal write buffer function with length 1 */
mbed_official 15:a81a8d6c1dfe 235 return _usart_write_buffer(module, (uint8_t *)tx_data, 1);
mbed_official 15:a81a8d6c1dfe 236 }
mbed_official 15:a81a8d6c1dfe 237
mbed_official 15:a81a8d6c1dfe 238 /**
mbed_official 15:a81a8d6c1dfe 239 * \brief Asynchronous read a data
mbed_official 15:a81a8d6c1dfe 240 *
mbed_official 15:a81a8d6c1dfe 241 * Sets up the driver to read data from the USART module to the data
mbed_official 15:a81a8d6c1dfe 242 * pointer given. If registered and enabled, a callback will be called
mbed_official 15:a81a8d6c1dfe 243 * when the receiving is completed.
mbed_official 15:a81a8d6c1dfe 244 *
mbed_official 15:a81a8d6c1dfe 245 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 246 * \param[out] rx_data Pointer to where received data should be put
mbed_official 15:a81a8d6c1dfe 247 *
mbed_official 15:a81a8d6c1dfe 248 * \returns Status of the operation.
mbed_official 15:a81a8d6c1dfe 249 * \retval STATUS_OK If operation was completed
mbed_official 15:a81a8d6c1dfe 250 * \retval STATUS_BUSY If operation was not completed
mbed_official 15:a81a8d6c1dfe 251 */
mbed_official 15:a81a8d6c1dfe 252 enum status_code usart_read_job(
mbed_official 15:a81a8d6c1dfe 253 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 254 uint16_t *const rx_data)
mbed_official 15:a81a8d6c1dfe 255 {
mbed_official 15:a81a8d6c1dfe 256 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 257 Assert(module);
mbed_official 15:a81a8d6c1dfe 258 Assert(rx_data);
mbed_official 15:a81a8d6c1dfe 259
mbed_official 15:a81a8d6c1dfe 260 /* Call internal read buffer function with length 1 */
mbed_official 15:a81a8d6c1dfe 261 return _usart_read_buffer(module, (uint8_t *)rx_data, 1);
mbed_official 15:a81a8d6c1dfe 262 }
mbed_official 15:a81a8d6c1dfe 263
mbed_official 15:a81a8d6c1dfe 264 /**
mbed_official 15:a81a8d6c1dfe 265 * \brief Asynchronous buffer write
mbed_official 15:a81a8d6c1dfe 266 *
mbed_official 15:a81a8d6c1dfe 267 * Sets up the driver to write a given buffer over the USART. If registered and
mbed_official 15:a81a8d6c1dfe 268 * enabled, a callback function will be called.
mbed_official 15:a81a8d6c1dfe 269 *
mbed_official 15:a81a8d6c1dfe 270 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 271 * \param[in] tx_data Pointer do data buffer to transmit
mbed_official 15:a81a8d6c1dfe 272 * \param[in] length Length of the data to transmit
mbed_official 15:a81a8d6c1dfe 273 *
mbed_official 15:a81a8d6c1dfe 274 * \note If using 9-bit data, the array that *tx_data point to should be defined
mbed_official 15:a81a8d6c1dfe 275 * as uint16_t array and should be casted to uint8_t* pointer. Because it
mbed_official 15:a81a8d6c1dfe 276 * is an address pointer, the highest byte is not discarded. For example:
mbed_official 15:a81a8d6c1dfe 277 * \code
mbed_official 15:a81a8d6c1dfe 278 #define TX_LEN 3
mbed_official 15:a81a8d6c1dfe 279 uint16_t tx_buf[TX_LEN] = {0x0111, 0x0022, 0x0133};
mbed_official 15:a81a8d6c1dfe 280 usart_write_buffer_job(&module, (uint8_t*)tx_buf, TX_LEN);
mbed_official 15:a81a8d6c1dfe 281 \endcode
mbed_official 15:a81a8d6c1dfe 282 *
mbed_official 15:a81a8d6c1dfe 283 * \returns Status of the operation.
mbed_official 15:a81a8d6c1dfe 284 * \retval STATUS_OK If operation was completed successfully.
mbed_official 15:a81a8d6c1dfe 285 * \retval STATUS_BUSY If operation was not completed, due to the
mbed_official 15:a81a8d6c1dfe 286 * USART module being busy
mbed_official 15:a81a8d6c1dfe 287 * \retval STATUS_ERR_INVALID_ARG If operation was not completed, due to invalid
mbed_official 15:a81a8d6c1dfe 288 * arguments
mbed_official 15:a81a8d6c1dfe 289 * \retval STATUS_ERR_DENIED If the transmitter is not enabled
mbed_official 15:a81a8d6c1dfe 290 */
mbed_official 15:a81a8d6c1dfe 291 enum status_code usart_write_buffer_job(
mbed_official 15:a81a8d6c1dfe 292 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 293 uint8_t *tx_data,
mbed_official 15:a81a8d6c1dfe 294 uint16_t length)
mbed_official 15:a81a8d6c1dfe 295 {
mbed_official 15:a81a8d6c1dfe 296 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 297 Assert(module);
mbed_official 15:a81a8d6c1dfe 298 Assert(tx_data);
mbed_official 15:a81a8d6c1dfe 299
mbed_official 15:a81a8d6c1dfe 300 if (length == 0) {
mbed_official 15:a81a8d6c1dfe 301 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 302 }
mbed_official 15:a81a8d6c1dfe 303
mbed_official 15:a81a8d6c1dfe 304 /* Check that the receiver is enabled */
mbed_official 15:a81a8d6c1dfe 305 if (!(module->transmitter_enabled)) {
mbed_official 15:a81a8d6c1dfe 306 return STATUS_ERR_DENIED;
mbed_official 15:a81a8d6c1dfe 307 }
mbed_official 15:a81a8d6c1dfe 308
mbed_official 15:a81a8d6c1dfe 309 /* Issue internal asynchronous write */
mbed_official 15:a81a8d6c1dfe 310 return _usart_write_buffer(module, tx_data, length);
mbed_official 15:a81a8d6c1dfe 311 }
mbed_official 15:a81a8d6c1dfe 312
mbed_official 15:a81a8d6c1dfe 313 /**
mbed_official 15:a81a8d6c1dfe 314 * \brief Asynchronous buffer read
mbed_official 15:a81a8d6c1dfe 315 *
mbed_official 15:a81a8d6c1dfe 316 * Sets up the driver to read from the USART to a given buffer. If registered
mbed_official 15:a81a8d6c1dfe 317 * and enabled, a callback function will be called.
mbed_official 15:a81a8d6c1dfe 318 *
mbed_official 15:a81a8d6c1dfe 319 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 320 * \param[out] rx_data Pointer to data buffer to receive
mbed_official 15:a81a8d6c1dfe 321 * \param[in] length Data buffer length
mbed_official 15:a81a8d6c1dfe 322 *
mbed_official 15:a81a8d6c1dfe 323 * \note If using 9-bit data, the array that *rx_data point to should be defined
mbed_official 15:a81a8d6c1dfe 324 * as uint16_t array and should be casted to uint8_t* pointer. Because it
mbed_official 15:a81a8d6c1dfe 325 * is an address pointer, the highest byte is not discarded. For example:
mbed_official 15:a81a8d6c1dfe 326 * \code
mbed_official 15:a81a8d6c1dfe 327 #define RX_LEN 3
mbed_official 15:a81a8d6c1dfe 328 uint16_t rx_buf[RX_LEN] = {0x0,};
mbed_official 15:a81a8d6c1dfe 329 usart_read_buffer_job(&module, (uint8_t*)rx_buf, RX_LEN);
mbed_official 15:a81a8d6c1dfe 330 \endcode
mbed_official 15:a81a8d6c1dfe 331 *
mbed_official 15:a81a8d6c1dfe 332 * \returns Status of the operation.
mbed_official 15:a81a8d6c1dfe 333 * \retval STATUS_OK If operation was completed
mbed_official 15:a81a8d6c1dfe 334 * \retval STATUS_BUSY If operation was not completed, due to the
mbed_official 15:a81a8d6c1dfe 335 * USART module being busy
mbed_official 15:a81a8d6c1dfe 336 * \retval STATUS_ERR_INVALID_ARG If operation was not completed, due to invalid
mbed_official 15:a81a8d6c1dfe 337 * arguments
mbed_official 15:a81a8d6c1dfe 338 * \retval STATUS_ERR_DENIED If the transmitter is not enabled
mbed_official 15:a81a8d6c1dfe 339 */
mbed_official 15:a81a8d6c1dfe 340 enum status_code usart_read_buffer_job(
mbed_official 15:a81a8d6c1dfe 341 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 342 uint8_t *rx_data,
mbed_official 15:a81a8d6c1dfe 343 uint16_t length)
mbed_official 15:a81a8d6c1dfe 344 {
mbed_official 15:a81a8d6c1dfe 345 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 346 Assert(module);
mbed_official 15:a81a8d6c1dfe 347 Assert(rx_data);
mbed_official 15:a81a8d6c1dfe 348
mbed_official 15:a81a8d6c1dfe 349 if (length == 0) {
mbed_official 15:a81a8d6c1dfe 350 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 351 }
mbed_official 15:a81a8d6c1dfe 352
mbed_official 15:a81a8d6c1dfe 353 /* Check that the receiver is enabled */
mbed_official 15:a81a8d6c1dfe 354 if (!(module->receiver_enabled)) {
mbed_official 15:a81a8d6c1dfe 355 return STATUS_ERR_DENIED;
mbed_official 15:a81a8d6c1dfe 356 }
mbed_official 15:a81a8d6c1dfe 357
mbed_official 15:a81a8d6c1dfe 358 /* Issue internal asynchronous read */
mbed_official 15:a81a8d6c1dfe 359 return _usart_read_buffer(module, rx_data, length);
mbed_official 15:a81a8d6c1dfe 360 }
mbed_official 15:a81a8d6c1dfe 361
mbed_official 15:a81a8d6c1dfe 362 /**
mbed_official 15:a81a8d6c1dfe 363 * \brief Cancels ongoing read/write operation
mbed_official 15:a81a8d6c1dfe 364 *
mbed_official 15:a81a8d6c1dfe 365 * Cancels the ongoing read/write operation modifying parameters in the
mbed_official 15:a81a8d6c1dfe 366 * USART software struct.
mbed_official 15:a81a8d6c1dfe 367 *
mbed_official 15:a81a8d6c1dfe 368 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 369 * \param[in] transceiver_type Transfer type to cancel
mbed_official 15:a81a8d6c1dfe 370 */
mbed_official 15:a81a8d6c1dfe 371 void usart_abort_job(
mbed_official 15:a81a8d6c1dfe 372 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 373 enum usart_transceiver_type transceiver_type)
mbed_official 15:a81a8d6c1dfe 374 {
mbed_official 15:a81a8d6c1dfe 375 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 376 Assert(module);
mbed_official 15:a81a8d6c1dfe 377 Assert(module->hw);
mbed_official 15:a81a8d6c1dfe 378
mbed_official 15:a81a8d6c1dfe 379 /* Get a pointer to the hardware module instance */
mbed_official 15:a81a8d6c1dfe 380 SercomUsart *const usart_hw = &(module->hw->USART);
mbed_official 15:a81a8d6c1dfe 381
mbed_official 15:a81a8d6c1dfe 382 switch(transceiver_type) {
mbed_official 15:a81a8d6c1dfe 383 case USART_TRANSCEIVER_RX:
mbed_official 15:a81a8d6c1dfe 384 /* Clear the interrupt flag in order to prevent the receive
mbed_official 15:a81a8d6c1dfe 385 * complete callback to fire */
mbed_official 15:a81a8d6c1dfe 386 usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 15:a81a8d6c1dfe 387
mbed_official 15:a81a8d6c1dfe 388 /* Clear the software reception buffer */
mbed_official 15:a81a8d6c1dfe 389 module->remaining_rx_buffer_length = 0;
mbed_official 15:a81a8d6c1dfe 390
mbed_official 15:a81a8d6c1dfe 391 break;
mbed_official 15:a81a8d6c1dfe 392
mbed_official 15:a81a8d6c1dfe 393 case USART_TRANSCEIVER_TX:
mbed_official 15:a81a8d6c1dfe 394 /* Clear the interrupt flag in order to prevent the receive
mbed_official 15:a81a8d6c1dfe 395 * complete callback to fire */
mbed_official 15:a81a8d6c1dfe 396 usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 15:a81a8d6c1dfe 397
mbed_official 15:a81a8d6c1dfe 398 /* Clear the software reception buffer */
mbed_official 15:a81a8d6c1dfe 399 module->remaining_tx_buffer_length = 0;
mbed_official 15:a81a8d6c1dfe 400
mbed_official 15:a81a8d6c1dfe 401 break;
mbed_official 15:a81a8d6c1dfe 402 }
mbed_official 15:a81a8d6c1dfe 403 }
mbed_official 15:a81a8d6c1dfe 404
mbed_official 15:a81a8d6c1dfe 405 /**
mbed_official 15:a81a8d6c1dfe 406 * \brief Get status from the ongoing or last asynchronous transfer operation
mbed_official 15:a81a8d6c1dfe 407 *
mbed_official 15:a81a8d6c1dfe 408 * Returns the error from a given ongoing or last asynchronous transfer operation.
mbed_official 15:a81a8d6c1dfe 409 * Either from a read or write transfer.
mbed_official 15:a81a8d6c1dfe 410 *
mbed_official 15:a81a8d6c1dfe 411 * \param[in] module Pointer to USART software instance struct
mbed_official 15:a81a8d6c1dfe 412 * \param[in] transceiver_type Transfer type to check
mbed_official 15:a81a8d6c1dfe 413 *
mbed_official 15:a81a8d6c1dfe 414 * \return Status of the given job.
mbed_official 15:a81a8d6c1dfe 415 * \retval STATUS_OK No error occurred during the last transfer
mbed_official 15:a81a8d6c1dfe 416 * \retval STATUS_BUSY A transfer is ongoing
mbed_official 15:a81a8d6c1dfe 417 * \retval STATUS_ERR_BAD_DATA The last operation was aborted due to a
mbed_official 15:a81a8d6c1dfe 418 * parity error. The transfer could be affected
mbed_official 15:a81a8d6c1dfe 419 * by external noise
mbed_official 15:a81a8d6c1dfe 420 * \retval STATUS_ERR_BAD_FORMAT The last operation was aborted due to a
mbed_official 15:a81a8d6c1dfe 421 * frame error
mbed_official 15:a81a8d6c1dfe 422 * \retval STATUS_ERR_OVERFLOW The last operation was aborted due to a
mbed_official 15:a81a8d6c1dfe 423 * buffer overflow
mbed_official 15:a81a8d6c1dfe 424 * \retval STATUS_ERR_INVALID_ARG An invalid transceiver enum given
mbed_official 15:a81a8d6c1dfe 425 */
mbed_official 15:a81a8d6c1dfe 426 enum status_code usart_get_job_status(
mbed_official 15:a81a8d6c1dfe 427 struct usart_module *const module,
mbed_official 15:a81a8d6c1dfe 428 enum usart_transceiver_type transceiver_type)
mbed_official 15:a81a8d6c1dfe 429 {
mbed_official 15:a81a8d6c1dfe 430 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 431 Assert(module);
mbed_official 15:a81a8d6c1dfe 432
mbed_official 15:a81a8d6c1dfe 433 /* Variable for status code */
mbed_official 15:a81a8d6c1dfe 434 enum status_code status_code;
mbed_official 15:a81a8d6c1dfe 435
mbed_official 15:a81a8d6c1dfe 436 switch(transceiver_type) {
mbed_official 15:a81a8d6c1dfe 437 case USART_TRANSCEIVER_RX:
mbed_official 15:a81a8d6c1dfe 438 status_code = module->rx_status;
mbed_official 15:a81a8d6c1dfe 439 break;
mbed_official 15:a81a8d6c1dfe 440
mbed_official 15:a81a8d6c1dfe 441 case USART_TRANSCEIVER_TX:
mbed_official 15:a81a8d6c1dfe 442 status_code = module->tx_status;
mbed_official 15:a81a8d6c1dfe 443 break;
mbed_official 15:a81a8d6c1dfe 444
mbed_official 15:a81a8d6c1dfe 445 default:
mbed_official 15:a81a8d6c1dfe 446 status_code = STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 447 break;
mbed_official 15:a81a8d6c1dfe 448 }
mbed_official 15:a81a8d6c1dfe 449
mbed_official 15:a81a8d6c1dfe 450 return status_code;
mbed_official 15:a81a8d6c1dfe 451 }
mbed_official 15:a81a8d6c1dfe 452
mbed_official 15:a81a8d6c1dfe 453 /**
mbed_official 15:a81a8d6c1dfe 454 * \internal
mbed_official 15:a81a8d6c1dfe 455 * Handles interrupts as they occur, and it will run callback functions
mbed_official 15:a81a8d6c1dfe 456 * which are registered and enabled.
mbed_official 15:a81a8d6c1dfe 457 *
mbed_official 15:a81a8d6c1dfe 458 * \param[in] instance ID of the SERCOM instance calling the interrupt
mbed_official 15:a81a8d6c1dfe 459 * handler.
mbed_official 15:a81a8d6c1dfe 460 */
mbed_official 15:a81a8d6c1dfe 461 void _usart_interrupt_handler(
mbed_official 15:a81a8d6c1dfe 462 uint8_t instance)
mbed_official 15:a81a8d6c1dfe 463 {
mbed_official 15:a81a8d6c1dfe 464 /* Temporary variables */
mbed_official 15:a81a8d6c1dfe 465 uint16_t interrupt_status;
mbed_official 15:a81a8d6c1dfe 466 uint16_t callback_status;
mbed_official 15:a81a8d6c1dfe 467 uint8_t error_code;
mbed_official 15:a81a8d6c1dfe 468
mbed_official 15:a81a8d6c1dfe 469
mbed_official 15:a81a8d6c1dfe 470 /* Get device instance from the look-up table */
mbed_official 15:a81a8d6c1dfe 471 struct usart_module *module
mbed_official 15:a81a8d6c1dfe 472 = (struct usart_module *)_sercom_instances[instance];
mbed_official 15:a81a8d6c1dfe 473
mbed_official 15:a81a8d6c1dfe 474 /* Pointer to the hardware module instance */
mbed_official 15:a81a8d6c1dfe 475 SercomUsart *const usart_hw
mbed_official 15:a81a8d6c1dfe 476 = &(module->hw->USART);
mbed_official 15:a81a8d6c1dfe 477
mbed_official 15:a81a8d6c1dfe 478 /* Wait for the synchronization to complete */
mbed_official 15:a81a8d6c1dfe 479 _usart_wait_for_sync(module);
mbed_official 15:a81a8d6c1dfe 480
mbed_official 15:a81a8d6c1dfe 481 /* Read and mask interrupt flag register */
mbed_official 15:a81a8d6c1dfe 482 interrupt_status = usart_hw->INTFLAG.reg;
mbed_official 15:a81a8d6c1dfe 483 interrupt_status &= usart_hw->INTENSET.reg;
mbed_official 15:a81a8d6c1dfe 484 callback_status = module->callback_reg_mask &
mbed_official 15:a81a8d6c1dfe 485 module->callback_enable_mask;
mbed_official 15:a81a8d6c1dfe 486
mbed_official 15:a81a8d6c1dfe 487 /* Check if a DATA READY interrupt has occurred,
mbed_official 15:a81a8d6c1dfe 488 * and if there is more to transfer */
mbed_official 15:a81a8d6c1dfe 489 if (interrupt_status & SERCOM_USART_INTFLAG_DRE) {
mbed_official 15:a81a8d6c1dfe 490 if (module->remaining_tx_buffer_length) {
mbed_official 15:a81a8d6c1dfe 491 /* Write value will be at least 8-bits long */
mbed_official 15:a81a8d6c1dfe 492 uint16_t data_to_send = *(module->tx_buffer_ptr);
mbed_official 15:a81a8d6c1dfe 493 /* Increment 8-bit pointer */
mbed_official 15:a81a8d6c1dfe 494 (module->tx_buffer_ptr)++;
mbed_official 15:a81a8d6c1dfe 495
mbed_official 15:a81a8d6c1dfe 496 if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
mbed_official 15:a81a8d6c1dfe 497 data_to_send |= (*(module->tx_buffer_ptr) << 8);
mbed_official 15:a81a8d6c1dfe 498 /* Increment 8-bit pointer */
mbed_official 15:a81a8d6c1dfe 499 (module->tx_buffer_ptr)++;
mbed_official 15:a81a8d6c1dfe 500 }
mbed_official 15:a81a8d6c1dfe 501 /* Write the data to send */
mbed_official 15:a81a8d6c1dfe 502 usart_hw->DATA.reg = (data_to_send & SERCOM_USART_DATA_MASK);
mbed_official 15:a81a8d6c1dfe 503
mbed_official 15:a81a8d6c1dfe 504 if (--(module->remaining_tx_buffer_length) == 0) {
mbed_official 15:a81a8d6c1dfe 505 /* Disable the Data Register Empty Interrupt */
mbed_official 15:a81a8d6c1dfe 506 usart_hw->INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
mbed_official 15:a81a8d6c1dfe 507 /* Enable Transmission Complete interrupt */
mbed_official 15:a81a8d6c1dfe 508 usart_hw->INTENSET.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 15:a81a8d6c1dfe 509
mbed_official 15:a81a8d6c1dfe 510 }
mbed_official 15:a81a8d6c1dfe 511 } else {
mbed_official 15:a81a8d6c1dfe 512 usart_hw->INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
mbed_official 15:a81a8d6c1dfe 513 }
mbed_official 15:a81a8d6c1dfe 514
mbed_official 15:a81a8d6c1dfe 515 /* Check if the Transmission Complete interrupt has occurred and
mbed_official 15:a81a8d6c1dfe 516 * that the transmit buffer is empty */
mbed_official 15:a81a8d6c1dfe 517 }
mbed_official 15:a81a8d6c1dfe 518
mbed_official 15:a81a8d6c1dfe 519 if (interrupt_status & SERCOM_USART_INTFLAG_TXC) {
mbed_official 15:a81a8d6c1dfe 520
mbed_official 15:a81a8d6c1dfe 521 /* Disable TX Complete Interrupt, and set STATUS_OK */
mbed_official 15:a81a8d6c1dfe 522 usart_hw->INTENCLR.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 15:a81a8d6c1dfe 523 module->tx_status = STATUS_OK;
mbed_official 15:a81a8d6c1dfe 524
mbed_official 15:a81a8d6c1dfe 525 /* Run callback if registered and enabled */
mbed_official 15:a81a8d6c1dfe 526 if (callback_status & (1 << USART_CALLBACK_BUFFER_TRANSMITTED)) {
mbed_official 15:a81a8d6c1dfe 527 (*(module->callback[USART_CALLBACK_BUFFER_TRANSMITTED]))(module);
mbed_official 15:a81a8d6c1dfe 528 }
mbed_official 15:a81a8d6c1dfe 529
mbed_official 15:a81a8d6c1dfe 530 /* Check if the Receive Complete interrupt has occurred, and that
mbed_official 15:a81a8d6c1dfe 531 * there's more data to receive */
mbed_official 15:a81a8d6c1dfe 532 }
mbed_official 15:a81a8d6c1dfe 533
mbed_official 15:a81a8d6c1dfe 534 if (interrupt_status & SERCOM_USART_INTFLAG_RXC) {
mbed_official 15:a81a8d6c1dfe 535
mbed_official 15:a81a8d6c1dfe 536 if (module->remaining_rx_buffer_length) {
mbed_official 15:a81a8d6c1dfe 537 /* Read out the status code and mask away all but the 4 LSBs*/
mbed_official 15:a81a8d6c1dfe 538 error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK);
mbed_official 15:a81a8d6c1dfe 539 #if !SAMD20
mbed_official 15:a81a8d6c1dfe 540 /* CTS status should not be considered as an error */
mbed_official 15:a81a8d6c1dfe 541 if(error_code & SERCOM_USART_STATUS_CTS) {
mbed_official 15:a81a8d6c1dfe 542 error_code &= ~SERCOM_USART_STATUS_CTS;
mbed_official 15:a81a8d6c1dfe 543 }
mbed_official 15:a81a8d6c1dfe 544 #endif
mbed_official 15:a81a8d6c1dfe 545 #ifdef FEATURE_USART_LIN_MASTER
mbed_official 15:a81a8d6c1dfe 546 /* TXE status should not be considered as an error */
mbed_official 15:a81a8d6c1dfe 547 if(error_code & SERCOM_USART_STATUS_TXE) {
mbed_official 15:a81a8d6c1dfe 548 error_code &= ~SERCOM_USART_STATUS_TXE;
mbed_official 15:a81a8d6c1dfe 549 }
mbed_official 15:a81a8d6c1dfe 550 #endif
mbed_official 15:a81a8d6c1dfe 551 /* Check if an error has occurred during the receiving */
mbed_official 15:a81a8d6c1dfe 552 if (error_code) {
mbed_official 15:a81a8d6c1dfe 553 /* Check which error occurred */
mbed_official 15:a81a8d6c1dfe 554 if (error_code & SERCOM_USART_STATUS_FERR) {
mbed_official 15:a81a8d6c1dfe 555 /* Store the error code and clear flag by writing 1 to it */
mbed_official 15:a81a8d6c1dfe 556 module->rx_status = STATUS_ERR_BAD_FORMAT;
mbed_official 15:a81a8d6c1dfe 557 usart_hw->STATUS.reg |= SERCOM_USART_STATUS_FERR;
mbed_official 15:a81a8d6c1dfe 558 } else if (error_code & SERCOM_USART_STATUS_BUFOVF) {
mbed_official 15:a81a8d6c1dfe 559 /* Store the error code and clear flag by writing 1 to it */
mbed_official 15:a81a8d6c1dfe 560 module->rx_status = STATUS_ERR_OVERFLOW;
mbed_official 15:a81a8d6c1dfe 561 usart_hw->STATUS.reg |= SERCOM_USART_STATUS_BUFOVF;
mbed_official 15:a81a8d6c1dfe 562 } else if (error_code & SERCOM_USART_STATUS_PERR) {
mbed_official 15:a81a8d6c1dfe 563 /* Store the error code and clear flag by writing 1 to it */
mbed_official 15:a81a8d6c1dfe 564 module->rx_status = STATUS_ERR_BAD_DATA;
mbed_official 15:a81a8d6c1dfe 565 usart_hw->STATUS.reg |= SERCOM_USART_STATUS_PERR;
mbed_official 15:a81a8d6c1dfe 566 }
mbed_official 15:a81a8d6c1dfe 567 #ifdef FEATURE_USART_LIN_SLAVE
mbed_official 15:a81a8d6c1dfe 568 else if (error_code & SERCOM_USART_STATUS_ISF) {
mbed_official 15:a81a8d6c1dfe 569 /* Store the error code and clear flag by writing 1 to it */
mbed_official 15:a81a8d6c1dfe 570 module->rx_status = STATUS_ERR_PROTOCOL;
mbed_official 15:a81a8d6c1dfe 571 usart_hw->STATUS.reg |= SERCOM_USART_STATUS_ISF;
mbed_official 15:a81a8d6c1dfe 572 }
mbed_official 15:a81a8d6c1dfe 573 #endif
mbed_official 15:a81a8d6c1dfe 574 #ifdef FEATURE_USART_COLLISION_DECTION
mbed_official 15:a81a8d6c1dfe 575 else if (error_code & SERCOM_USART_STATUS_COLL) {
mbed_official 15:a81a8d6c1dfe 576 /* Store the error code and clear flag by writing 1 to it */
mbed_official 15:a81a8d6c1dfe 577 module->rx_status = STATUS_ERR_PACKET_COLLISION;
mbed_official 15:a81a8d6c1dfe 578 usart_hw->STATUS.reg |= SERCOM_USART_STATUS_COLL;
mbed_official 15:a81a8d6c1dfe 579 }
mbed_official 15:a81a8d6c1dfe 580 #endif
mbed_official 15:a81a8d6c1dfe 581
mbed_official 15:a81a8d6c1dfe 582 /* Run callback if registered and enabled */
mbed_official 15:a81a8d6c1dfe 583 if (callback_status
mbed_official 15:a81a8d6c1dfe 584 & (1 << USART_CALLBACK_ERROR)) {
mbed_official 15:a81a8d6c1dfe 585 (*(module->callback[USART_CALLBACK_ERROR]))(module);
mbed_official 15:a81a8d6c1dfe 586 }
mbed_official 15:a81a8d6c1dfe 587
mbed_official 15:a81a8d6c1dfe 588 } else {
mbed_official 15:a81a8d6c1dfe 589
mbed_official 15:a81a8d6c1dfe 590 /* Read current packet from DATA register,
mbed_official 15:a81a8d6c1dfe 591 * increment buffer pointer and decrement buffer length */
mbed_official 15:a81a8d6c1dfe 592 uint16_t received_data = (usart_hw->DATA.reg & SERCOM_USART_DATA_MASK);
mbed_official 15:a81a8d6c1dfe 593
mbed_official 15:a81a8d6c1dfe 594 /* Read value will be at least 8-bits long */
mbed_official 15:a81a8d6c1dfe 595 *(module->rx_buffer_ptr) = received_data;
mbed_official 15:a81a8d6c1dfe 596 /* Increment 8-bit pointer */
mbed_official 15:a81a8d6c1dfe 597 module->rx_buffer_ptr += 1;
mbed_official 15:a81a8d6c1dfe 598
mbed_official 15:a81a8d6c1dfe 599 if (module->character_size == USART_CHARACTER_SIZE_9BIT) {
mbed_official 15:a81a8d6c1dfe 600 /* 9-bit data, write next received byte to the buffer */
mbed_official 15:a81a8d6c1dfe 601 *(module->rx_buffer_ptr) = (received_data >> 8);
mbed_official 15:a81a8d6c1dfe 602 /* Increment 8-bit pointer */
mbed_official 15:a81a8d6c1dfe 603 module->rx_buffer_ptr += 1;
mbed_official 15:a81a8d6c1dfe 604 }
mbed_official 15:a81a8d6c1dfe 605
mbed_official 15:a81a8d6c1dfe 606 /* Check if the last character have been received */
mbed_official 15:a81a8d6c1dfe 607 if(--(module->remaining_rx_buffer_length) == 0) {
mbed_official 15:a81a8d6c1dfe 608 /* Disable RX Complete Interrupt,
mbed_official 15:a81a8d6c1dfe 609 * and set STATUS_OK */
mbed_official 15:a81a8d6c1dfe 610 usart_hw->INTENCLR.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 15:a81a8d6c1dfe 611 module->rx_status = STATUS_OK;
mbed_official 15:a81a8d6c1dfe 612
mbed_official 15:a81a8d6c1dfe 613 /* Run callback if registered and enabled */
mbed_official 15:a81a8d6c1dfe 614 if (callback_status
mbed_official 15:a81a8d6c1dfe 615 & (1 << USART_CALLBACK_BUFFER_RECEIVED)) {
mbed_official 15:a81a8d6c1dfe 616 (*(module->callback[USART_CALLBACK_BUFFER_RECEIVED]))(module);
mbed_official 15:a81a8d6c1dfe 617 }
mbed_official 15:a81a8d6c1dfe 618 }
mbed_official 15:a81a8d6c1dfe 619 }
mbed_official 15:a81a8d6c1dfe 620 } else {
mbed_official 15:a81a8d6c1dfe 621 /* This should not happen. Disable Receive Complete interrupt. */
mbed_official 15:a81a8d6c1dfe 622 usart_hw->INTENCLR.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 15:a81a8d6c1dfe 623 }
mbed_official 15:a81a8d6c1dfe 624 }
mbed_official 15:a81a8d6c1dfe 625
mbed_official 15:a81a8d6c1dfe 626 #ifdef FEATURE_USART_HARDWARE_FLOW_CONTROL
mbed_official 15:a81a8d6c1dfe 627 if (interrupt_status & SERCOM_USART_INTFLAG_CTSIC) {
mbed_official 15:a81a8d6c1dfe 628 /* Disable interrupts */
mbed_official 15:a81a8d6c1dfe 629 usart_hw->INTENCLR.reg = SERCOM_USART_INTENCLR_CTSIC;
mbed_official 15:a81a8d6c1dfe 630 /* Clear interrupt flag */
mbed_official 15:a81a8d6c1dfe 631 usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_CTSIC;
mbed_official 15:a81a8d6c1dfe 632
mbed_official 15:a81a8d6c1dfe 633 /* Run callback if registered and enabled */
mbed_official 15:a81a8d6c1dfe 634 if (callback_status & (1 << USART_CALLBACK_CTS_INPUT_CHANGE)) {
mbed_official 15:a81a8d6c1dfe 635 (*(module->callback[USART_CALLBACK_CTS_INPUT_CHANGE]))(module);
mbed_official 15:a81a8d6c1dfe 636 }
mbed_official 15:a81a8d6c1dfe 637 }
mbed_official 15:a81a8d6c1dfe 638 #endif
mbed_official 15:a81a8d6c1dfe 639
mbed_official 15:a81a8d6c1dfe 640 #ifdef FEATURE_USART_LIN_SLAVE
mbed_official 15:a81a8d6c1dfe 641 if (interrupt_status & SERCOM_USART_INTFLAG_RXBRK) {
mbed_official 15:a81a8d6c1dfe 642 /* Disable interrupts */
mbed_official 15:a81a8d6c1dfe 643 usart_hw->INTENCLR.reg = SERCOM_USART_INTENCLR_RXBRK;
mbed_official 15:a81a8d6c1dfe 644 /* Clear interrupt flag */
mbed_official 15:a81a8d6c1dfe 645 usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_RXBRK;
mbed_official 15:a81a8d6c1dfe 646
mbed_official 15:a81a8d6c1dfe 647 /* Run callback if registered and enabled */
mbed_official 15:a81a8d6c1dfe 648 if (callback_status & (1 << USART_CALLBACK_BREAK_RECEIVED)) {
mbed_official 15:a81a8d6c1dfe 649 (*(module->callback[USART_CALLBACK_BREAK_RECEIVED]))(module);
mbed_official 15:a81a8d6c1dfe 650 }
mbed_official 15:a81a8d6c1dfe 651 }
mbed_official 15:a81a8d6c1dfe 652 #endif
mbed_official 15:a81a8d6c1dfe 653
mbed_official 15:a81a8d6c1dfe 654 #ifdef FEATURE_USART_START_FRAME_DECTION
mbed_official 15:a81a8d6c1dfe 655 if (interrupt_status & SERCOM_USART_INTFLAG_RXS) {
mbed_official 15:a81a8d6c1dfe 656 /* Disable interrupts */
mbed_official 15:a81a8d6c1dfe 657 usart_hw->INTENCLR.reg = SERCOM_USART_INTENCLR_RXS;
mbed_official 15:a81a8d6c1dfe 658 /* Clear interrupt flag */
mbed_official 15:a81a8d6c1dfe 659 usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_RXS;
mbed_official 15:a81a8d6c1dfe 660
mbed_official 15:a81a8d6c1dfe 661 /* Run callback if registered and enabled */
mbed_official 15:a81a8d6c1dfe 662 if (callback_status & (1 << USART_CALLBACK_START_RECEIVED)) {
mbed_official 15:a81a8d6c1dfe 663 (*(module->callback[USART_CALLBACK_START_RECEIVED]))(module);
mbed_official 15:a81a8d6c1dfe 664 }
mbed_official 15:a81a8d6c1dfe 665 }
mbed_official 15:a81a8d6c1dfe 666 #endif
mbed_official 15:a81a8d6c1dfe 667 }
mbed_official 15:a81a8d6c1dfe 668