Lancaster University's (short term!) clone of mbed-src for micro:bit. This is a copy of the github branch https://github.com/lancaster-university/mbed-classic

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri Jul 17 09:15:10 2015 +0100
Revision:
592:a274ee790e56
Parent:
579:53297373a894
Synchronized with git revision e7144f83a8d75df80c4877936b6ffe552b0be9e6

Full URL: https://github.com/mbedmicro/mbed/commit/e7144f83a8d75df80c4877936b6ffe552b0be9e6/

More API implementation for SAMR21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 579:53297373a894 1 /* mbed Microcontroller Library
mbed_official 579:53297373a894 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 579:53297373a894 3 *
mbed_official 579:53297373a894 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 579:53297373a894 5 * you may not use this file except in compliance with the License.
mbed_official 579:53297373a894 6 * You may obtain a copy of the License at
mbed_official 579:53297373a894 7 *
mbed_official 579:53297373a894 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 579:53297373a894 9 *
mbed_official 579:53297373a894 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 579:53297373a894 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 579:53297373a894 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 579:53297373a894 13 * See the License for the specific language governing permissions and
mbed_official 579:53297373a894 14 * limitations under the License.
mbed_official 579:53297373a894 15 */
mbed_official 579:53297373a894 16 #include <string.h>
mbed_official 579:53297373a894 17 #include "mbed_assert.h"
mbed_official 579:53297373a894 18 #include "cmsis.h"
mbed_official 579:53297373a894 19 #include "serial_api.h"
mbed_official 579:53297373a894 20 #include "pinmap.h"
mbed_official 579:53297373a894 21 #include "PeripheralPins.h"
mbed_official 579:53297373a894 22 #include "usart.h"
mbed_official 592:a274ee790e56 23 #include "pinmap_function.h"
mbed_official 592:a274ee790e56 24
mbed_official 592:a274ee790e56 25 #define USART_TX_INDEX 0
mbed_official 592:a274ee790e56 26 #define USART_RX_INDEX 1
mbed_official 592:a274ee790e56 27 #define USART_RXFLOW_INDEX 2
mbed_official 592:a274ee790e56 28 #define USART_TXFLOW_INDEX 3
mbed_official 579:53297373a894 29
mbed_official 579:53297373a894 30 #if DEVICE_SERIAL_ASYNCH
mbed_official 579:53297373a894 31 #define pUSART_S(obj) obj->serial.usart
mbed_official 579:53297373a894 32 #define pSERIAL_S(obj) ((struct serial_s*)&(obj->serial))
mbed_official 579:53297373a894 33 #else
mbed_official 579:53297373a894 34 #define pUSART_S(obj) obj->serial
mbed_official 579:53297373a894 35 #define pSERIAL_S(obj) ((struct serial_s*)obj)
mbed_official 579:53297373a894 36 #endif
mbed_official 579:53297373a894 37 #define _USART(obj) pUSART_S(obj)->USART
mbed_official 579:53297373a894 38 #define USART_NUM 6
mbed_official 579:53297373a894 39
mbed_official 579:53297373a894 40
mbed_official 579:53297373a894 41 uint8_t serial_get_index(serial_t *obj);
mbed_official 579:53297373a894 42 IRQn_Type get_serial_irq_num (serial_t *obj);
mbed_official 592:a274ee790e56 43 uint32_t get_serial_vector (serial_t *obj);
mbed_official 592:a274ee790e56 44 void uart0_irq();
mbed_official 592:a274ee790e56 45 void uart1_irq();
mbed_official 592:a274ee790e56 46 void uart2_irq();
mbed_official 592:a274ee790e56 47 void uart3_irq();
mbed_official 592:a274ee790e56 48 void uart4_irq();
mbed_official 592:a274ee790e56 49 void uart5_irq();
mbed_official 579:53297373a894 50
mbed_official 579:53297373a894 51 static uint32_t serial_irq_ids[USART_NUM] = {0};
mbed_official 579:53297373a894 52 static uart_irq_handler irq_handler;
mbed_official 579:53297373a894 53
mbed_official 579:53297373a894 54 int stdio_uart_inited = 0;
mbed_official 579:53297373a894 55 serial_t stdio_uart;
mbed_official 579:53297373a894 56
mbed_official 579:53297373a894 57 extern uint8_t g_sys_init;
mbed_official 579:53297373a894 58
mbed_official 579:53297373a894 59 static inline bool usart_syncing(serial_t *obj)
mbed_official 579:53297373a894 60 {
mbed_official 579:53297373a894 61 /* Sanity check arguments */
mbed_official 579:53297373a894 62 MBED_ASSERT(obj);
mbed_official 579:53297373a894 63
mbed_official 579:53297373a894 64 return (_USART(obj).SYNCBUSY.reg);
mbed_official 579:53297373a894 65 }
mbed_official 579:53297373a894 66
mbed_official 579:53297373a894 67 static inline void enable_usart(serial_t *obj)
mbed_official 579:53297373a894 68 {
mbed_official 579:53297373a894 69 /* Sanity check arguments */
mbed_official 579:53297373a894 70 MBED_ASSERT(obj);
mbed_official 579:53297373a894 71
mbed_official 579:53297373a894 72 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 73 usart_syncing(obj);
mbed_official 579:53297373a894 74
mbed_official 579:53297373a894 75 /* Enable USART module */
mbed_official 579:53297373a894 76 _USART(obj).CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
mbed_official 579:53297373a894 77 }
mbed_official 579:53297373a894 78
mbed_official 579:53297373a894 79 static inline void disable_usart(serial_t *obj)
mbed_official 579:53297373a894 80 {
mbed_official 579:53297373a894 81 /* Sanity check arguments */
mbed_official 579:53297373a894 82 MBED_ASSERT(obj);
mbed_official 579:53297373a894 83
mbed_official 579:53297373a894 84 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 85 usart_syncing(obj);
mbed_official 579:53297373a894 86
mbed_official 579:53297373a894 87 /* Disable USART module */
mbed_official 579:53297373a894 88 _USART(obj).CTRLA.reg &= ~SERCOM_USART_CTRLA_ENABLE;
mbed_official 579:53297373a894 89 }
mbed_official 579:53297373a894 90
mbed_official 579:53297373a894 91 static inline void reset_usart(serial_t *obj)
mbed_official 579:53297373a894 92 {
mbed_official 579:53297373a894 93 /* Sanity check arguments */
mbed_official 579:53297373a894 94 MBED_ASSERT(obj);
mbed_official 579:53297373a894 95
mbed_official 579:53297373a894 96 disable_usart(obj);
mbed_official 579:53297373a894 97
mbed_official 579:53297373a894 98 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 99 usart_syncing(obj);
mbed_official 579:53297373a894 100
mbed_official 579:53297373a894 101 /* Reset module */
mbed_official 579:53297373a894 102 _USART(obj).CTRLA.reg = SERCOM_USART_CTRLA_SWRST;
mbed_official 579:53297373a894 103 }
mbed_official 579:53297373a894 104
mbed_official 592:a274ee790e56 105 uint32_t serial_find_mux_settings (serial_t *obj)
mbed_official 579:53297373a894 106 {
mbed_official 592:a274ee790e56 107 /* Sanity check arguments */
mbed_official 592:a274ee790e56 108 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 109 uint32_t mux_setting = 0;
mbed_official 592:a274ee790e56 110 uint32_t pinpad[4] = {0};
mbed_official 592:a274ee790e56 111 uint8_t i = 0;
mbed_official 592:a274ee790e56 112 uint32_t sercom_index = pinmap_merge_sercom(pSERIAL_S(obj)->pins[0], pSERIAL_S(obj)->pins[1]);
mbed_official 579:53297373a894 113
mbed_official 592:a274ee790e56 114 for (i = 0; i < 4 ; i++) {
mbed_official 592:a274ee790e56 115 pinpad[i] = pinmap_pad_sercom(pSERIAL_S(obj)->pins[i], sercom_index);
mbed_official 592:a274ee790e56 116 }
mbed_official 592:a274ee790e56 117
mbed_official 592:a274ee790e56 118 switch(pinpad[USART_RX_INDEX]) {
mbed_official 592:a274ee790e56 119 case 0:
mbed_official 592:a274ee790e56 120 mux_setting |= SERCOM_USART_CTRLA_RXPO(0);
mbed_official 592:a274ee790e56 121 break;
mbed_official 592:a274ee790e56 122 case 1:
mbed_official 592:a274ee790e56 123 mux_setting |= SERCOM_USART_CTRLA_RXPO(1);
mbed_official 592:a274ee790e56 124 break;
mbed_official 592:a274ee790e56 125 case 2:
mbed_official 592:a274ee790e56 126 mux_setting |= SERCOM_USART_CTRLA_RXPO(2);
mbed_official 592:a274ee790e56 127 break;
mbed_official 592:a274ee790e56 128 case 3:
mbed_official 592:a274ee790e56 129 mux_setting |= SERCOM_USART_CTRLA_RXPO(3);
mbed_official 592:a274ee790e56 130 break;
mbed_official 592:a274ee790e56 131 }
mbed_official 592:a274ee790e56 132
mbed_official 592:a274ee790e56 133 if ((pSERIAL_S(obj)->pins[USART_RXFLOW_INDEX] == NC) && (pSERIAL_S(obj)->pins[USART_TXFLOW_INDEX] == NC)) {
mbed_official 592:a274ee790e56 134 if (pinpad[USART_TX_INDEX] == 0) {
mbed_official 592:a274ee790e56 135 mux_setting |= SERCOM_USART_CTRLA_TXPO(0);
mbed_official 592:a274ee790e56 136 } else if(pinpad[USART_RX_INDEX] == 2) {
mbed_official 592:a274ee790e56 137 mux_setting |= SERCOM_USART_CTRLA_TXPO(1);
mbed_official 592:a274ee790e56 138 } else {
mbed_official 592:a274ee790e56 139 mux_setting = mux_setting; // dummy condition
mbed_official 592:a274ee790e56 140 }
mbed_official 592:a274ee790e56 141 } else { // for hardware flow control and uart // expecting the tx in pad 0, rts in pad2 and cts in pad 3
mbed_official 592:a274ee790e56 142 if((pinpad[USART_TX_INDEX] == 0) && (pinpad[USART_RXFLOW_INDEX]/*rts pin*/ == 2) && (pinpad[USART_TXFLOW_INDEX] /*cts pin*/ == 3)) {
mbed_official 592:a274ee790e56 143 mux_setting |= SERCOM_USART_CTRLA_TXPO(2);
mbed_official 592:a274ee790e56 144 }
mbed_official 592:a274ee790e56 145 }
mbed_official 592:a274ee790e56 146 return mux_setting;
mbed_official 592:a274ee790e56 147 }
mbed_official 592:a274ee790e56 148
mbed_official 592:a274ee790e56 149 static enum status_code usart_set_config_default(serial_t *obj)
mbed_official 592:a274ee790e56 150 {
mbed_official 592:a274ee790e56 151 /* Sanity check arguments */
mbed_official 592:a274ee790e56 152 MBED_ASSERT(obj);
mbed_official 579:53297373a894 153 /* Index for generic clock */
mbed_official 579:53297373a894 154 uint32_t sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj));
mbed_official 579:53297373a894 155 uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
mbed_official 579:53297373a894 156
mbed_official 579:53297373a894 157 /* Cache new register values to minimize the number of register writes */
mbed_official 579:53297373a894 158 uint32_t ctrla = 0;
mbed_official 579:53297373a894 159 uint32_t ctrlb = 0;
mbed_official 579:53297373a894 160 uint16_t baud = 0;
mbed_official 579:53297373a894 161
mbed_official 579:53297373a894 162 enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
mbed_official 579:53297373a894 163 enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
mbed_official 579:53297373a894 164
mbed_official 579:53297373a894 165 /* Set data order, internal muxing, and clock polarity */
mbed_official 579:53297373a894 166 ctrla = (uint32_t)USART_DATAORDER_LSB | // data order
mbed_official 579:53297373a894 167 (uint32_t)pSERIAL_S(obj)->mux_setting; // mux setting // clock polarity is not used
mbed_official 579:53297373a894 168
mbed_official 579:53297373a894 169
mbed_official 579:53297373a894 170 /* Get baud value from mode and clock */
mbed_official 579:53297373a894 171 _sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate,system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num); // for asynchronous transfer mode
mbed_official 579:53297373a894 172
mbed_official 579:53297373a894 173 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 174 usart_syncing(obj);
mbed_official 579:53297373a894 175
mbed_official 579:53297373a894 176 /*Set baud val */
mbed_official 579:53297373a894 177 _USART(obj).BAUD.reg = baud;
mbed_official 579:53297373a894 178
mbed_official 579:53297373a894 179 /* Set sample mode */
mbed_official 579:53297373a894 180 ctrla |= USART_TRANSFER_ASYNCHRONOUSLY;
mbed_official 579:53297373a894 181
mbed_official 579:53297373a894 182 /* for disabled external clock source */
mbed_official 579:53297373a894 183 ctrla |= SERCOM_USART_CTRLA_MODE(0x1);
mbed_official 579:53297373a894 184
mbed_official 579:53297373a894 185 /* Set stopbits, character size and enable transceivers */
mbed_official 579:53297373a894 186 ctrlb = (uint32_t)pSERIAL_S(obj)->stopbits | (uint32_t)pSERIAL_S(obj)->character_size |
mbed_official 579:53297373a894 187 (0x1ul << SERCOM_USART_CTRLB_RXEN_Pos) | // receiver enable
mbed_official 579:53297373a894 188 (0x1ul << SERCOM_USART_CTRLB_TXEN_Pos); // transmitter enable
mbed_official 579:53297373a894 189
mbed_official 579:53297373a894 190 /* Check parity mode bits */
mbed_official 579:53297373a894 191 if (pSERIAL_S(obj)->parity != USART_PARITY_NONE) {
mbed_official 579:53297373a894 192 ctrla |= SERCOM_USART_CTRLA_FORM(1);
mbed_official 579:53297373a894 193 ctrlb |= pSERIAL_S(obj)->parity;
mbed_official 579:53297373a894 194 } else {
mbed_official 579:53297373a894 195 ctrla |= SERCOM_USART_CTRLA_FORM(0);
mbed_official 579:53297373a894 196 }
mbed_official 579:53297373a894 197
mbed_official 579:53297373a894 198 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 199 usart_syncing(obj);
mbed_official 579:53297373a894 200
mbed_official 579:53297373a894 201 /* Write configuration to CTRLB */
mbed_official 579:53297373a894 202 _USART(obj).CTRLB.reg = ctrlb;
mbed_official 579:53297373a894 203
mbed_official 579:53297373a894 204 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 205 usart_syncing(obj);
mbed_official 579:53297373a894 206
mbed_official 579:53297373a894 207 /* Write configuration to CTRLA */
mbed_official 579:53297373a894 208 _USART(obj).CTRLA.reg = ctrla;
mbed_official 579:53297373a894 209
mbed_official 579:53297373a894 210 return STATUS_OK;
mbed_official 579:53297373a894 211 }
mbed_official 579:53297373a894 212
mbed_official 579:53297373a894 213 void get_default_serial_values(serial_t *obj)
mbed_official 579:53297373a894 214 {
mbed_official 592:a274ee790e56 215 /* Sanity check arguments */
mbed_official 592:a274ee790e56 216 MBED_ASSERT(obj);
mbed_official 579:53297373a894 217 /* Set default config to object */
mbed_official 579:53297373a894 218 pSERIAL_S(obj)->parity = USART_PARITY_NONE;
mbed_official 579:53297373a894 219 pSERIAL_S(obj)->stopbits = USART_STOPBITS_1;
mbed_official 579:53297373a894 220 pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT;
mbed_official 579:53297373a894 221 pSERIAL_S(obj)->baudrate = 9600;
mbed_official 579:53297373a894 222 pSERIAL_S(obj)->mux_setting = USART_RX_1_TX_2_XCK_3;
mbed_official 579:53297373a894 223 };
mbed_official 579:53297373a894 224
mbed_official 579:53297373a894 225 void serial_init(serial_t *obj, PinName tx, PinName rx)
mbed_official 579:53297373a894 226 {
mbed_official 592:a274ee790e56 227 /* Sanity check arguments */
mbed_official 592:a274ee790e56 228 MBED_ASSERT(obj);
mbed_official 579:53297373a894 229 if (g_sys_init == 0) {
mbed_official 579:53297373a894 230 system_init();
mbed_official 579:53297373a894 231 g_sys_init = 1;
mbed_official 579:53297373a894 232 }
mbed_official 579:53297373a894 233 struct system_gclk_chan_config gclk_chan_conf;
mbed_official 579:53297373a894 234 UARTName uart;
mbed_official 579:53297373a894 235 uint32_t gclk_index;
mbed_official 579:53297373a894 236 uint32_t pm_index;
mbed_official 579:53297373a894 237 uint32_t sercom_index = 0;
mbed_official 579:53297373a894 238 uint32_t muxsetting = 0;
mbed_official 579:53297373a894 239
mbed_official 579:53297373a894 240 /* Disable USART module */
mbed_official 579:53297373a894 241 disable_usart(obj);
mbed_official 579:53297373a894 242
mbed_official 579:53297373a894 243 get_default_serial_values(obj);
mbed_official 579:53297373a894 244
mbed_official 592:a274ee790e56 245 pSERIAL_S(obj)->pins[USART_TX_INDEX] = tx;
mbed_official 592:a274ee790e56 246 pSERIAL_S(obj)->pins[USART_RX_INDEX] = rx;
mbed_official 592:a274ee790e56 247 pSERIAL_S(obj)->pins[USART_RXFLOW_INDEX] = NC;
mbed_official 592:a274ee790e56 248 pSERIAL_S(obj)->pins[USART_TXFLOW_INDEX] = NC;
mbed_official 592:a274ee790e56 249
mbed_official 592:a274ee790e56 250 muxsetting = serial_find_mux_settings(obj); // getting mux setting from pins
mbed_official 592:a274ee790e56 251 sercom_index = pinmap_merge_sercom(tx, rx); // same variable sercom_index reused for optimization
mbed_official 592:a274ee790e56 252 if (sercom_index == (uint32_t)NC) {
mbed_official 592:a274ee790e56 253 /*expecting a valid value for sercom index*/
mbed_official 592:a274ee790e56 254 return;
mbed_official 579:53297373a894 255 }
mbed_official 592:a274ee790e56 256 sercom_index &= 0x0F;
mbed_official 592:a274ee790e56 257 uart = pinmap_peripheral_sercom(NC, sercom_index);
mbed_official 592:a274ee790e56 258 pUSART_S(obj) = (Sercom *)uart;
mbed_official 579:53297373a894 259
mbed_official 579:53297373a894 260 pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos;
mbed_official 579:53297373a894 261 gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
mbed_official 579:53297373a894 262
mbed_official 579:53297373a894 263 if (_USART(obj).CTRLA.reg & SERCOM_USART_CTRLA_SWRST) {
mbed_official 592:a274ee790e56 264 return; /* The module is busy resetting itself */
mbed_official 579:53297373a894 265 }
mbed_official 579:53297373a894 266
mbed_official 579:53297373a894 267 if (_USART(obj).CTRLA.reg & SERCOM_USART_CTRLA_ENABLE) {
mbed_official 592:a274ee790e56 268 return; /* Check the module is enabled */
mbed_official 579:53297373a894 269 }
mbed_official 579:53297373a894 270
mbed_official 579:53297373a894 271 /* Turn on module in PM */
mbed_official 579:53297373a894 272 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
mbed_official 579:53297373a894 273
mbed_official 579:53297373a894 274 /* Set up the GCLK for the module */
mbed_official 579:53297373a894 275 gclk_chan_conf.source_generator = GCLK_GENERATOR_0;
mbed_official 579:53297373a894 276 system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
mbed_official 579:53297373a894 277 system_gclk_chan_enable(gclk_index);
mbed_official 579:53297373a894 278 sercom_set_gclk_generator(GCLK_GENERATOR_0, false);
mbed_official 579:53297373a894 279
mbed_official 592:a274ee790e56 280 pSERIAL_S(obj)->mux_setting = muxsetting;
mbed_official 579:53297373a894 281 /* Set configuration according to the config struct */
mbed_official 579:53297373a894 282 usart_set_config_default(obj);
mbed_official 592:a274ee790e56 283
mbed_official 579:53297373a894 284 struct system_pinmux_config pin_conf;
mbed_official 579:53297373a894 285 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
mbed_official 579:53297373a894 286 pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
mbed_official 592:a274ee790e56 287 pin_conf.powersave = false;
mbed_official 579:53297373a894 288
mbed_official 579:53297373a894 289 /* Configure the SERCOM pins according to the user configuration */
mbed_official 579:53297373a894 290 for (uint8_t pad = 0; pad < 4; pad++) {
mbed_official 592:a274ee790e56 291 uint32_t current_pin = pSERIAL_S(obj)->pins[pad];
mbed_official 592:a274ee790e56 292 if (current_pin != (uint32_t)NC) {
mbed_official 592:a274ee790e56 293 pin_conf.mux_position = pinmap_function_sercom(current_pin, sercom_index);
mbed_official 592:a274ee790e56 294 if ((uint8_t)NC != pin_conf.mux_position) {
mbed_official 592:a274ee790e56 295 system_pinmux_pin_set_config(current_pin, &pin_conf);
mbed_official 592:a274ee790e56 296 }
mbed_official 579:53297373a894 297 }
mbed_official 579:53297373a894 298 }
mbed_official 579:53297373a894 299
mbed_official 579:53297373a894 300 if (uart == STDIO_UART) {
mbed_official 579:53297373a894 301 stdio_uart_inited = 1;
mbed_official 579:53297373a894 302 memcpy(&stdio_uart, obj, sizeof(serial_t));
mbed_official 579:53297373a894 303 }
mbed_official 579:53297373a894 304 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 305 usart_syncing(obj);
mbed_official 579:53297373a894 306
mbed_official 579:53297373a894 307 /* Enable USART module */
mbed_official 579:53297373a894 308 enable_usart(obj);
mbed_official 579:53297373a894 309 }
mbed_official 579:53297373a894 310
mbed_official 579:53297373a894 311 void serial_free(serial_t *obj)
mbed_official 579:53297373a894 312 {
mbed_official 592:a274ee790e56 313 /* Sanity check arguments */
mbed_official 592:a274ee790e56 314 MBED_ASSERT(obj);
mbed_official 579:53297373a894 315 serial_irq_ids[serial_get_index(obj)] = 0;
mbed_official 579:53297373a894 316 disable_usart(obj);
mbed_official 579:53297373a894 317 }
mbed_official 579:53297373a894 318
mbed_official 579:53297373a894 319 void serial_baud(serial_t *obj, int baudrate)
mbed_official 579:53297373a894 320 {
mbed_official 592:a274ee790e56 321 /* Sanity check arguments */
mbed_official 592:a274ee790e56 322 MBED_ASSERT(obj);
mbed_official 579:53297373a894 323 MBED_ASSERT((baudrate == 110) || (baudrate == 150) || (baudrate == 300) || (baudrate == 1200) ||
mbed_official 579:53297373a894 324 (baudrate == 2400) || (baudrate == 4800) || (baudrate == 9600) || (baudrate == 19200) || (baudrate == 38400) ||
mbed_official 579:53297373a894 325 (baudrate == 57600) || (baudrate == 115200) || (baudrate == 230400) || (baudrate == 460800) || (baudrate == 921600) );
mbed_official 579:53297373a894 326
mbed_official 579:53297373a894 327 struct system_gclk_chan_config gclk_chan_conf;
mbed_official 579:53297373a894 328 uint32_t gclk_index;
mbed_official 579:53297373a894 329 uint16_t baud = 0;
mbed_official 579:53297373a894 330 uint32_t sercom_index = 0;
mbed_official 579:53297373a894 331 enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC;
mbed_official 579:53297373a894 332 enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16;
mbed_official 579:53297373a894 333
mbed_official 579:53297373a894 334 pSERIAL_S(obj)->baudrate = baudrate;
mbed_official 579:53297373a894 335 disable_usart(obj);
mbed_official 579:53297373a894 336
mbed_official 579:53297373a894 337 sercom_index = _sercom_get_sercom_inst_index(pUSART_S(obj));
mbed_official 579:53297373a894 338 gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
mbed_official 579:53297373a894 339
mbed_official 579:53297373a894 340 gclk_chan_conf.source_generator = GCLK_GENERATOR_0;
mbed_official 579:53297373a894 341 system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
mbed_official 579:53297373a894 342 system_gclk_chan_enable(gclk_index);
mbed_official 579:53297373a894 343 sercom_set_gclk_generator(GCLK_GENERATOR_0, false);
mbed_official 579:53297373a894 344
mbed_official 579:53297373a894 345 /* Get baud value from mode and clock */
mbed_official 579:53297373a894 346 _sercom_get_async_baud_val(pSERIAL_S(obj)->baudrate, system_gclk_chan_get_hz(gclk_index), &baud, mode, sample_num);
mbed_official 579:53297373a894 347
mbed_official 579:53297373a894 348 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 349 usart_syncing(obj);
mbed_official 579:53297373a894 350
mbed_official 579:53297373a894 351 /*Set baud val */
mbed_official 579:53297373a894 352 _USART(obj).BAUD.reg = baud;
mbed_official 579:53297373a894 353 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 354 usart_syncing(obj);
mbed_official 579:53297373a894 355
mbed_official 579:53297373a894 356 enable_usart(obj);
mbed_official 579:53297373a894 357 }
mbed_official 579:53297373a894 358
mbed_official 579:53297373a894 359 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
mbed_official 579:53297373a894 360 {
mbed_official 592:a274ee790e56 361 /* Sanity check arguments */
mbed_official 592:a274ee790e56 362 MBED_ASSERT(obj);
mbed_official 579:53297373a894 363 MBED_ASSERT((stop_bits == 1) || (stop_bits == 2));
mbed_official 579:53297373a894 364 MBED_ASSERT((parity == ParityNone) || (parity == ParityOdd) || (parity == ParityEven));
mbed_official 579:53297373a894 365 MBED_ASSERT((data_bits == 5) || (data_bits == 6) || (data_bits == 7) || (data_bits == 8) /*|| (data_bits == 9)*/);
mbed_official 579:53297373a894 366
mbed_official 579:53297373a894 367 /* Cache new register values to minimize the number of register writes */
mbed_official 579:53297373a894 368 uint32_t ctrla = 0;
mbed_official 579:53297373a894 369 uint32_t ctrlb = 0;
mbed_official 579:53297373a894 370
mbed_official 579:53297373a894 371 disable_usart(obj);
mbed_official 579:53297373a894 372
mbed_official 579:53297373a894 373 ctrla = _USART(obj).CTRLA.reg;
mbed_official 579:53297373a894 374 ctrlb = _USART(obj).CTRLB.reg;
mbed_official 579:53297373a894 375
mbed_official 579:53297373a894 376 ctrla &= ~(SERCOM_USART_CTRLA_FORM_Msk);
mbed_official 579:53297373a894 377 ctrlb &= ~(SERCOM_USART_CTRLB_CHSIZE_Msk);
mbed_official 579:53297373a894 378 ctrlb &= ~(SERCOM_USART_CTRLB_SBMODE);
mbed_official 579:53297373a894 379 ctrlb &= ~(SERCOM_USART_CTRLB_PMODE);
mbed_official 579:53297373a894 380
mbed_official 579:53297373a894 381 switch (stop_bits) {
mbed_official 579:53297373a894 382 case 1:
mbed_official 579:53297373a894 383 pSERIAL_S(obj)->stopbits = USART_STOPBITS_1;
mbed_official 579:53297373a894 384 break;
mbed_official 579:53297373a894 385 case 2:
mbed_official 579:53297373a894 386 pSERIAL_S(obj)->stopbits = USART_STOPBITS_2;
mbed_official 579:53297373a894 387 break;
mbed_official 579:53297373a894 388 default:
mbed_official 579:53297373a894 389 pSERIAL_S(obj)->stopbits = USART_STOPBITS_1;
mbed_official 579:53297373a894 390 }
mbed_official 579:53297373a894 391
mbed_official 579:53297373a894 392 switch (parity) {
mbed_official 579:53297373a894 393 case ParityNone:
mbed_official 579:53297373a894 394 pSERIAL_S(obj)->parity = USART_PARITY_NONE;
mbed_official 579:53297373a894 395 break;
mbed_official 579:53297373a894 396 case ParityOdd:
mbed_official 579:53297373a894 397 pSERIAL_S(obj)->parity = USART_PARITY_ODD;
mbed_official 579:53297373a894 398 break;
mbed_official 579:53297373a894 399 case ParityEven:
mbed_official 579:53297373a894 400 pSERIAL_S(obj)->parity = USART_PARITY_EVEN;
mbed_official 579:53297373a894 401 break;
mbed_official 579:53297373a894 402 default:
mbed_official 579:53297373a894 403 pSERIAL_S(obj)->parity = USART_PARITY_NONE;
mbed_official 579:53297373a894 404 }
mbed_official 579:53297373a894 405
mbed_official 579:53297373a894 406 switch (data_bits) {
mbed_official 579:53297373a894 407 case 5:
mbed_official 579:53297373a894 408 pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_5BIT;
mbed_official 579:53297373a894 409 break;
mbed_official 579:53297373a894 410 case 6:
mbed_official 579:53297373a894 411 pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_6BIT;
mbed_official 579:53297373a894 412 break;
mbed_official 579:53297373a894 413 case 7:
mbed_official 579:53297373a894 414 pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_7BIT;
mbed_official 579:53297373a894 415 break;
mbed_official 579:53297373a894 416 case 8:
mbed_official 579:53297373a894 417 pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT;
mbed_official 579:53297373a894 418 break; // 9 bit transfer not required in mbed
mbed_official 579:53297373a894 419 default:
mbed_official 579:53297373a894 420 pSERIAL_S(obj)->character_size = USART_CHARACTER_SIZE_8BIT;
mbed_official 579:53297373a894 421 }
mbed_official 579:53297373a894 422
mbed_official 579:53297373a894 423
mbed_official 579:53297373a894 424 /* Set stopbits, character size and enable transceivers */
mbed_official 579:53297373a894 425 ctrlb = (uint32_t)pSERIAL_S(obj)->stopbits | (uint32_t)pSERIAL_S(obj)->character_size;
mbed_official 579:53297373a894 426
mbed_official 579:53297373a894 427 /* Check parity mode bits */
mbed_official 579:53297373a894 428 if (pSERIAL_S(obj)->parity != USART_PARITY_NONE) {
mbed_official 579:53297373a894 429 ctrla |= SERCOM_USART_CTRLA_FORM(1);
mbed_official 579:53297373a894 430 ctrlb |= pSERIAL_S(obj)->parity;
mbed_official 579:53297373a894 431 } else {
mbed_official 579:53297373a894 432 ctrla |= SERCOM_USART_CTRLA_FORM(0);
mbed_official 579:53297373a894 433 }
mbed_official 579:53297373a894 434
mbed_official 579:53297373a894 435 /* Write configuration to CTRLB */
mbed_official 579:53297373a894 436 _USART(obj).CTRLB.reg = ctrlb;
mbed_official 579:53297373a894 437
mbed_official 579:53297373a894 438 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 439 usart_syncing(obj);
mbed_official 579:53297373a894 440
mbed_official 579:53297373a894 441 /* Write configuration to CTRLA */
mbed_official 579:53297373a894 442 _USART(obj).CTRLA.reg = ctrla;
mbed_official 579:53297373a894 443
mbed_official 579:53297373a894 444 /* Wait until synchronization is complete */
mbed_official 579:53297373a894 445 usart_syncing(obj);
mbed_official 579:53297373a894 446
mbed_official 579:53297373a894 447 enable_usart(obj);
mbed_official 579:53297373a894 448 }
mbed_official 579:53297373a894 449
mbed_official 579:53297373a894 450 #ifdef DEVICE_SERIAL_FC
mbed_official 579:53297373a894 451
mbed_official 579:53297373a894 452 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
mbed_official 579:53297373a894 453 {
mbed_official 592:a274ee790e56 454 /* Sanity check arguments */
mbed_official 592:a274ee790e56 455 MBED_ASSERT(obj);
mbed_official 579:53297373a894 456 uint32_t muxsetting = 0;
mbed_official 579:53297373a894 457 uint32_t sercom_index = 0;
mbed_official 579:53297373a894 458 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 579:53297373a894 459 uint32_t vector = 0;
mbed_official 579:53297373a894 460
mbed_official 592:a274ee790e56 461 pSERIAL_S(obj)->pins[USART_RXFLOW_INDEX] = rxflow;
mbed_official 592:a274ee790e56 462 pSERIAL_S(obj)->pins[USART_TXFLOW_INDEX] = txflow;
mbed_official 592:a274ee790e56 463 muxsetting = serial_find_mux_settings(obj); // getting mux setting from pins
mbed_official 592:a274ee790e56 464 sercom_index = pinmap_merge_sercom(pSERIAL_S(obj)->pins[USART_TX_INDEX], pSERIAL_S(obj)->pins[USART_RX_INDEX]); // same variable sercom_index reused for optimization
mbed_official 592:a274ee790e56 465 if (sercom_index == (uint32_t)NC) {
mbed_official 592:a274ee790e56 466 /*expecting a valid value for sercom index*/
mbed_official 592:a274ee790e56 467 return;
mbed_official 579:53297373a894 468 }
mbed_official 592:a274ee790e56 469
mbed_official 592:a274ee790e56 470 vector = get_serial_vector(obj);
mbed_official 579:53297373a894 471 irq_n = get_serial_irq_num(obj);
mbed_official 579:53297373a894 472
mbed_official 579:53297373a894 473 disable_usart(obj);
mbed_official 579:53297373a894 474
mbed_official 579:53297373a894 475 /* Set configuration according to the config struct */
mbed_official 592:a274ee790e56 476 pSERIAL_S(obj)->mux_setting = muxsetting; // mux setting to be changed for configuring hardware control
mbed_official 579:53297373a894 477 usart_set_config_default(obj);
mbed_official 579:53297373a894 478
mbed_official 579:53297373a894 479 struct system_pinmux_config pin_conf;
mbed_official 579:53297373a894 480 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
mbed_official 579:53297373a894 481 pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
mbed_official 592:a274ee790e56 482 pin_conf.powersave = false;
mbed_official 579:53297373a894 483
mbed_official 592:a274ee790e56 484 for (uint8_t pad = 0; pad < 2; pad++) { // setting for rx and tx
mbed_official 592:a274ee790e56 485 uint32_t current_pin = pSERIAL_S(obj)->pins[pad];
mbed_official 592:a274ee790e56 486 if (current_pin != (uint32_t)NC) {
mbed_official 592:a274ee790e56 487 pin_conf.mux_position = pinmap_function_sercom(current_pin, sercom_index);
mbed_official 592:a274ee790e56 488 if ((uint8_t)NC != pin_conf.mux_position) {
mbed_official 592:a274ee790e56 489 system_pinmux_pin_set_config(current_pin, &pin_conf);
mbed_official 592:a274ee790e56 490 }
mbed_official 579:53297373a894 491 }
mbed_official 579:53297373a894 492 }
mbed_official 592:a274ee790e56 493 if((FlowControlRTS == type) || (FlowControlRTSCTS== type)) {
mbed_official 592:a274ee790e56 494 if (pSERIAL_S(obj)->pins[USART_RXFLOW_INDEX] != NC) {
mbed_official 592:a274ee790e56 495 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT; // setting for rxflow
mbed_official 592:a274ee790e56 496 pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_UP;
mbed_official 592:a274ee790e56 497 pin_conf.mux_position = pinmap_function_sercom(pSERIAL_S(obj)->pins[USART_RXFLOW_INDEX] , sercom_index);
mbed_official 592:a274ee790e56 498 if ((uint8_t)NC != pin_conf.mux_position) {
mbed_official 592:a274ee790e56 499 system_pinmux_pin_set_config(pSERIAL_S(obj)->pins[USART_RXFLOW_INDEX], &pin_conf);
mbed_official 592:a274ee790e56 500 }
mbed_official 592:a274ee790e56 501 }
mbed_official 579:53297373a894 502 }
mbed_official 592:a274ee790e56 503 if((FlowControlCTS == type) || (FlowControlRTSCTS== type)) {
mbed_official 592:a274ee790e56 504 if (pSERIAL_S(obj)->pins[USART_TXFLOW_INDEX] != NC) {
mbed_official 592:a274ee790e56 505 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; // setting for txflow
mbed_official 592:a274ee790e56 506 pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_UP;
mbed_official 592:a274ee790e56 507 pin_conf.mux_position = pinmap_function_sercom(pSERIAL_S(obj)->pins[USART_TXFLOW_INDEX] , sercom_index);
mbed_official 592:a274ee790e56 508 if ((uint8_t)NC != pin_conf.mux_position) {
mbed_official 592:a274ee790e56 509 system_pinmux_pin_set_config(pSERIAL_S(obj)->pins[USART_TXFLOW_INDEX], &pin_conf);
mbed_official 592:a274ee790e56 510 }
mbed_official 592:a274ee790e56 511 }
mbed_official 592:a274ee790e56 512 }
mbed_official 592:a274ee790e56 513 enable_usart(obj);
mbed_official 592:a274ee790e56 514 }
mbed_official 579:53297373a894 515
mbed_official 592:a274ee790e56 516 #endif //DEVICE_SERIAL_FC
mbed_official 579:53297373a894 517
mbed_official 579:53297373a894 518 void serial_break_set(serial_t *obj)
mbed_official 579:53297373a894 519 {
mbed_official 592:a274ee790e56 520 /* Sanity check arguments */
mbed_official 592:a274ee790e56 521 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 522 struct system_pinmux_config pin_conf;
mbed_official 592:a274ee790e56 523 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
mbed_official 592:a274ee790e56 524 pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
mbed_official 592:a274ee790e56 525 pin_conf.mux_position = SYSTEM_PINMUX_GPIO;
mbed_official 592:a274ee790e56 526 pin_conf.powersave = false;
mbed_official 592:a274ee790e56 527
mbed_official 592:a274ee790e56 528 if (pSERIAL_S(obj)->pins[USART_TX_INDEX] != NC) {
mbed_official 592:a274ee790e56 529 system_pinmux_pin_set_config(pSERIAL_S(obj)->pins[USART_TX_INDEX], &pin_conf);
mbed_official 592:a274ee790e56 530 }
mbed_official 579:53297373a894 531 }
mbed_official 579:53297373a894 532
mbed_official 579:53297373a894 533 void serial_break_clear(serial_t *obj)
mbed_official 579:53297373a894 534 {
mbed_official 592:a274ee790e56 535 /* Sanity check arguments */
mbed_official 592:a274ee790e56 536 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 537 uint32_t sercom_index = pinmap_merge_sercom(pSERIAL_S(obj)->pins[USART_TX_INDEX], pSERIAL_S(obj)->pins[USART_RX_INDEX]);
mbed_official 592:a274ee790e56 538
mbed_official 592:a274ee790e56 539 struct system_pinmux_config pin_conf;
mbed_official 592:a274ee790e56 540 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
mbed_official 592:a274ee790e56 541 pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
mbed_official 592:a274ee790e56 542 pin_conf.powersave = false;
mbed_official 592:a274ee790e56 543
mbed_official 592:a274ee790e56 544 if (pSERIAL_S(obj)->pins[USART_TX_INDEX] != NC) {
mbed_official 592:a274ee790e56 545 pin_conf.mux_position = pinmap_function_sercom(pSERIAL_S(obj)->pins[USART_TX_INDEX], sercom_index);
mbed_official 592:a274ee790e56 546 if ((uint8_t)NC != pin_conf.mux_position) {
mbed_official 592:a274ee790e56 547 system_pinmux_pin_set_config(pSERIAL_S(obj)->pins[USART_TX_INDEX], &pin_conf);
mbed_official 592:a274ee790e56 548 }
mbed_official 592:a274ee790e56 549 }
mbed_official 579:53297373a894 550 }
mbed_official 579:53297373a894 551
mbed_official 579:53297373a894 552 /******************************************************************************
mbed_official 579:53297373a894 553 * INTERRUPTS HANDLING
mbed_official 579:53297373a894 554 ******************************************************************************/
mbed_official 579:53297373a894 555 inline uint8_t serial_get_index(serial_t *obj)
mbed_official 579:53297373a894 556 {
mbed_official 592:a274ee790e56 557 /* Sanity check arguments */
mbed_official 592:a274ee790e56 558 MBED_ASSERT(obj);
mbed_official 579:53297373a894 559 switch ((int)pUSART_S(obj)) {
mbed_official 579:53297373a894 560 case UART_0:
mbed_official 579:53297373a894 561 return 0;
mbed_official 579:53297373a894 562 case UART_1:
mbed_official 579:53297373a894 563 return 1;
mbed_official 579:53297373a894 564 case UART_2:
mbed_official 579:53297373a894 565 return 2;
mbed_official 579:53297373a894 566 case UART_3:
mbed_official 579:53297373a894 567 return 3;
mbed_official 579:53297373a894 568 case UART_4:
mbed_official 579:53297373a894 569 return 4;
mbed_official 579:53297373a894 570 case UART_5:
mbed_official 579:53297373a894 571 return 5;
mbed_official 579:53297373a894 572 }
mbed_official 579:53297373a894 573 return 0;
mbed_official 579:53297373a894 574 }
mbed_official 592:a274ee790e56 575
mbed_official 579:53297373a894 576 static inline void uart_irq(SercomUsart *const usart, uint32_t index)
mbed_official 579:53297373a894 577 {
mbed_official 592:a274ee790e56 578 MBED_ASSERT(usart != (void*)0);
mbed_official 579:53297373a894 579 uint16_t interrupt_status;
mbed_official 579:53297373a894 580 interrupt_status = usart->INTFLAG.reg;
mbed_official 579:53297373a894 581 interrupt_status &= usart->INTENSET.reg;
mbed_official 579:53297373a894 582
mbed_official 579:53297373a894 583 if (serial_irq_ids[index] != 0) {
mbed_official 579:53297373a894 584 if (interrupt_status & SERCOM_USART_INTFLAG_TXC) { // for transmit complete
mbed_official 579:53297373a894 585 usart->INTFLAG.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 579:53297373a894 586 irq_handler(serial_irq_ids[index], TxIrq);
mbed_official 579:53297373a894 587 }
mbed_official 579:53297373a894 588 if (interrupt_status & SERCOM_USART_INTFLAG_RXC) { // for receive complete
mbed_official 579:53297373a894 589 usart->INTFLAG.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 579:53297373a894 590 irq_handler(serial_irq_ids[index], RxIrq);
mbed_official 579:53297373a894 591 }
mbed_official 579:53297373a894 592 }
mbed_official 579:53297373a894 593 }
mbed_official 579:53297373a894 594
mbed_official 579:53297373a894 595 void uart0_irq()
mbed_official 579:53297373a894 596 {
mbed_official 579:53297373a894 597 uart_irq((SercomUsart *)UART_0, 0);
mbed_official 579:53297373a894 598 }
mbed_official 579:53297373a894 599
mbed_official 579:53297373a894 600 void uart1_irq()
mbed_official 579:53297373a894 601 {
mbed_official 579:53297373a894 602 uart_irq((SercomUsart *)UART_1, 1);
mbed_official 579:53297373a894 603 }
mbed_official 579:53297373a894 604
mbed_official 579:53297373a894 605 void uart2_irq()
mbed_official 579:53297373a894 606 {
mbed_official 579:53297373a894 607 uart_irq((SercomUsart *)UART_2, 2);
mbed_official 579:53297373a894 608 }
mbed_official 579:53297373a894 609
mbed_official 579:53297373a894 610 void uart3_irq()
mbed_official 579:53297373a894 611 {
mbed_official 579:53297373a894 612 uart_irq((SercomUsart *)UART_3, 3);
mbed_official 579:53297373a894 613 }
mbed_official 579:53297373a894 614
mbed_official 579:53297373a894 615 void uart4_irq()
mbed_official 579:53297373a894 616 {
mbed_official 579:53297373a894 617 uart_irq((SercomUsart *)UART_4, 4);
mbed_official 579:53297373a894 618 }
mbed_official 579:53297373a894 619
mbed_official 579:53297373a894 620 void uart5_irq()
mbed_official 579:53297373a894 621 {
mbed_official 579:53297373a894 622 uart_irq((SercomUsart *)UART_5, 5);
mbed_official 579:53297373a894 623 }
mbed_official 579:53297373a894 624
mbed_official 592:a274ee790e56 625 uint32_t get_serial_vector (serial_t *obj)
mbed_official 579:53297373a894 626 {
mbed_official 592:a274ee790e56 627 /* Sanity check arguments */
mbed_official 592:a274ee790e56 628 MBED_ASSERT(obj);
mbed_official 579:53297373a894 629 uint32_t vector = 0;
mbed_official 579:53297373a894 630 switch ((int)pUSART_S(obj)) {
mbed_official 579:53297373a894 631 case UART_0:
mbed_official 579:53297373a894 632 vector = (uint32_t)uart0_irq;
mbed_official 579:53297373a894 633 break;
mbed_official 579:53297373a894 634 case UART_1:
mbed_official 579:53297373a894 635 vector = (uint32_t)uart1_irq;
mbed_official 579:53297373a894 636 break;
mbed_official 579:53297373a894 637 case UART_2:
mbed_official 579:53297373a894 638 vector = (uint32_t)uart2_irq;
mbed_official 579:53297373a894 639 break;
mbed_official 579:53297373a894 640 case UART_3:
mbed_official 579:53297373a894 641 vector = (uint32_t)uart3_irq;
mbed_official 579:53297373a894 642 break;
mbed_official 579:53297373a894 643 case UART_4:
mbed_official 579:53297373a894 644 vector = (uint32_t)uart4_irq;
mbed_official 579:53297373a894 645 break;
mbed_official 579:53297373a894 646 case UART_5:
mbed_official 579:53297373a894 647 vector = (uint32_t)uart5_irq;
mbed_official 579:53297373a894 648 break;
mbed_official 579:53297373a894 649 }
mbed_official 592:a274ee790e56 650 return vector;
mbed_official 592:a274ee790e56 651 }
mbed_official 592:a274ee790e56 652
mbed_official 592:a274ee790e56 653 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
mbed_official 592:a274ee790e56 654 {
mbed_official 592:a274ee790e56 655 /* Sanity check arguments */
mbed_official 592:a274ee790e56 656 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 657 irq_handler = handler;
mbed_official 592:a274ee790e56 658 serial_irq_ids[serial_get_index(obj)] = id;
mbed_official 592:a274ee790e56 659 }
mbed_official 592:a274ee790e56 660
mbed_official 592:a274ee790e56 661 IRQn_Type get_serial_irq_num (serial_t *obj)
mbed_official 592:a274ee790e56 662 {
mbed_official 592:a274ee790e56 663 /* Sanity check arguments */
mbed_official 592:a274ee790e56 664 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 665 switch ((int)pUSART_S(obj)) {
mbed_official 592:a274ee790e56 666 case UART_0:
mbed_official 592:a274ee790e56 667 return SERCOM0_IRQn;
mbed_official 592:a274ee790e56 668 case UART_1:
mbed_official 592:a274ee790e56 669 return SERCOM1_IRQn;
mbed_official 592:a274ee790e56 670 case UART_2:
mbed_official 592:a274ee790e56 671 return SERCOM2_IRQn;
mbed_official 592:a274ee790e56 672 case UART_3:
mbed_official 592:a274ee790e56 673 return SERCOM3_IRQn;
mbed_official 592:a274ee790e56 674 case UART_4:
mbed_official 592:a274ee790e56 675 return SERCOM4_IRQn;
mbed_official 592:a274ee790e56 676 case UART_5:
mbed_official 592:a274ee790e56 677 return SERCOM5_IRQn;
mbed_official 592:a274ee790e56 678 default:
mbed_official 592:a274ee790e56 679 MBED_ASSERT(0);
mbed_official 592:a274ee790e56 680 }
mbed_official 592:a274ee790e56 681 return SERCOM0_IRQn; // to avoid warning
mbed_official 592:a274ee790e56 682 }
mbed_official 592:a274ee790e56 683
mbed_official 592:a274ee790e56 684 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
mbed_official 592:a274ee790e56 685 {
mbed_official 592:a274ee790e56 686 /* Sanity check arguments */
mbed_official 592:a274ee790e56 687 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 688 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 592:a274ee790e56 689 uint32_t vector = 0;
mbed_official 592:a274ee790e56 690
mbed_official 592:a274ee790e56 691 vector = get_serial_vector(obj);
mbed_official 579:53297373a894 692 irq_n = get_serial_irq_num(obj);
mbed_official 579:53297373a894 693
mbed_official 579:53297373a894 694 if (enable) {
mbed_official 579:53297373a894 695 switch (irq) {
mbed_official 579:53297373a894 696 case RxIrq:
mbed_official 579:53297373a894 697 _USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 579:53297373a894 698 break;
mbed_official 579:53297373a894 699 case TxIrq:
mbed_official 579:53297373a894 700 _USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 579:53297373a894 701 break;
mbed_official 579:53297373a894 702 }
mbed_official 579:53297373a894 703 NVIC_SetVector(irq_n, vector);
mbed_official 579:53297373a894 704 NVIC_EnableIRQ(irq_n);
mbed_official 579:53297373a894 705
mbed_official 579:53297373a894 706 } else {
mbed_official 579:53297373a894 707 switch (irq) {
mbed_official 579:53297373a894 708 case RxIrq:
mbed_official 579:53297373a894 709 _USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 579:53297373a894 710 break;
mbed_official 579:53297373a894 711 case TxIrq:
mbed_official 579:53297373a894 712 _USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 579:53297373a894 713 break;
mbed_official 579:53297373a894 714 }
mbed_official 579:53297373a894 715 NVIC_DisableIRQ(irq_n);
mbed_official 579:53297373a894 716 }
mbed_official 579:53297373a894 717 }
mbed_official 579:53297373a894 718
mbed_official 579:53297373a894 719 /******************************************************************************
mbed_official 579:53297373a894 720 * READ/WRITE
mbed_official 579:53297373a894 721 ******************************************************************************/
mbed_official 579:53297373a894 722 int serial_getc(serial_t *obj)
mbed_official 579:53297373a894 723 {
mbed_official 592:a274ee790e56 724 /* Sanity check arguments */
mbed_official 592:a274ee790e56 725 MBED_ASSERT(obj);
mbed_official 579:53297373a894 726 while (!serial_readable(obj));
mbed_official 579:53297373a894 727 return _USART(obj).DATA.reg ;
mbed_official 579:53297373a894 728 }
mbed_official 579:53297373a894 729
mbed_official 579:53297373a894 730 void serial_putc(serial_t *obj, int c)
mbed_official 579:53297373a894 731 {
mbed_official 592:a274ee790e56 732 /* Sanity check arguments */
mbed_official 592:a274ee790e56 733 MBED_ASSERT(obj);
mbed_official 579:53297373a894 734 uint16_t q = (c & SERCOM_USART_DATA_MASK);
mbed_official 579:53297373a894 735 while (!serial_writable(obj));
mbed_official 579:53297373a894 736 _USART(obj).DATA.reg = q;
mbed_official 579:53297373a894 737 while (!(_USART(obj).INTFLAG.reg & SERCOM_USART_INTFLAG_TXC)); // wait till data is sent
mbed_official 579:53297373a894 738 }
mbed_official 579:53297373a894 739
mbed_official 579:53297373a894 740 int serial_readable(serial_t *obj)
mbed_official 579:53297373a894 741 {
mbed_official 592:a274ee790e56 742 /* Sanity check arguments */
mbed_official 592:a274ee790e56 743 MBED_ASSERT(obj);
mbed_official 579:53297373a894 744 uint32_t status = 1;
mbed_official 579:53297373a894 745 if (!(_USART(obj).INTFLAG.reg & SERCOM_USART_INTFLAG_RXC)) {
mbed_official 579:53297373a894 746 status = 0;
mbed_official 579:53297373a894 747 } else {
mbed_official 579:53297373a894 748 status = 1;
mbed_official 579:53297373a894 749 }
mbed_official 579:53297373a894 750 return status;
mbed_official 579:53297373a894 751 }
mbed_official 579:53297373a894 752
mbed_official 579:53297373a894 753 int serial_writable(serial_t *obj)
mbed_official 579:53297373a894 754 {
mbed_official 592:a274ee790e56 755 /* Sanity check arguments */
mbed_official 592:a274ee790e56 756 MBED_ASSERT(obj);
mbed_official 579:53297373a894 757 uint32_t status = 1;
mbed_official 579:53297373a894 758 if (!(_USART(obj).INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) {
mbed_official 579:53297373a894 759 status = 0;
mbed_official 579:53297373a894 760 } else {
mbed_official 579:53297373a894 761 status = 1;
mbed_official 579:53297373a894 762 }
mbed_official 579:53297373a894 763 return status;
mbed_official 579:53297373a894 764 }
mbed_official 579:53297373a894 765
mbed_official 579:53297373a894 766 /************************************************************************************
mbed_official 579:53297373a894 767 * ASYNCHRONOUS HAL *
mbed_official 579:53297373a894 768 ************************************************************************************/
mbed_official 579:53297373a894 769
mbed_official 579:53297373a894 770 #if DEVICE_SERIAL_ASYNCH
mbed_official 579:53297373a894 771
mbed_official 579:53297373a894 772 /************************************
mbed_official 579:53297373a894 773 * HELPER FUNCTIONS *
mbed_official 579:53297373a894 774 ***********************************/
mbed_official 579:53297373a894 775 void serial_tx_enable_event(serial_t *obj, int event, uint8_t enable)
mbed_official 579:53297373a894 776 {
mbed_official 592:a274ee790e56 777 /* Sanity check arguments */
mbed_official 592:a274ee790e56 778 MBED_ASSERT(obj);
mbed_official 579:53297373a894 779 if(enable) {
mbed_official 579:53297373a894 780 pSERIAL_S(obj)->events |= event;
mbed_official 579:53297373a894 781 } else {
mbed_official 579:53297373a894 782 pSERIAL_S(obj)->events &= ~ event;
mbed_official 579:53297373a894 783 }
mbed_official 579:53297373a894 784 }
mbed_official 579:53297373a894 785
mbed_official 579:53297373a894 786 void serial_rx_enable_event(serial_t *obj, int event, uint8_t enable)
mbed_official 579:53297373a894 787 {
mbed_official 592:a274ee790e56 788 /* Sanity check arguments */
mbed_official 592:a274ee790e56 789 MBED_ASSERT(obj);
mbed_official 579:53297373a894 790 if(enable) {
mbed_official 579:53297373a894 791 pSERIAL_S(obj)->events |= event;
mbed_official 579:53297373a894 792 } else {
mbed_official 579:53297373a894 793 pSERIAL_S(obj)->events &= ~ event;
mbed_official 579:53297373a894 794 }
mbed_official 579:53297373a894 795 }
mbed_official 579:53297373a894 796
mbed_official 579:53297373a894 797 void serial_tx_buffer_set(serial_t *obj, void *tx, int tx_length, uint8_t width)
mbed_official 579:53297373a894 798 {
mbed_official 592:a274ee790e56 799 /* Sanity check arguments */
mbed_official 592:a274ee790e56 800 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 801 MBED_ASSERT(tx != (void*)0);
mbed_official 579:53297373a894 802 // We only support byte buffers for now
mbed_official 579:53297373a894 803 MBED_ASSERT(width == 8);
mbed_official 579:53297373a894 804
mbed_official 579:53297373a894 805 if(serial_tx_active(obj)) return;
mbed_official 579:53297373a894 806
mbed_official 579:53297373a894 807 obj->tx_buff.buffer = tx;
mbed_official 579:53297373a894 808 obj->tx_buff.length = tx_length;
mbed_official 579:53297373a894 809 obj->tx_buff.pos = 0;
mbed_official 579:53297373a894 810
mbed_official 579:53297373a894 811 return;
mbed_official 579:53297373a894 812 }
mbed_official 579:53297373a894 813
mbed_official 579:53297373a894 814 void serial_rx_buffer_set(serial_t *obj, void *rx, int rx_length, uint8_t width)
mbed_official 579:53297373a894 815 {
mbed_official 592:a274ee790e56 816 /* Sanity check arguments */
mbed_official 592:a274ee790e56 817 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 818 MBED_ASSERT(rx != (void*)0);
mbed_official 579:53297373a894 819 // We only support byte buffers for now
mbed_official 579:53297373a894 820 MBED_ASSERT(width == 8);
mbed_official 579:53297373a894 821
mbed_official 579:53297373a894 822 if(serial_rx_active(obj)) return;
mbed_official 579:53297373a894 823
mbed_official 579:53297373a894 824 obj->rx_buff.buffer = rx;
mbed_official 579:53297373a894 825 obj->rx_buff.length = rx_length;
mbed_official 579:53297373a894 826 obj->rx_buff.pos = 0;
mbed_official 579:53297373a894 827
mbed_official 579:53297373a894 828 return;
mbed_official 579:53297373a894 829 }
mbed_official 579:53297373a894 830
mbed_official 579:53297373a894 831 void serial_set_char_match(serial_t *obj, uint8_t char_match)
mbed_official 579:53297373a894 832 {
mbed_official 592:a274ee790e56 833 /* Sanity check arguments */
mbed_official 592:a274ee790e56 834 MBED_ASSERT(obj);
mbed_official 579:53297373a894 835 if (char_match != SERIAL_RESERVED_CHAR_MATCH) {
mbed_official 579:53297373a894 836 obj->char_match = char_match;
mbed_official 579:53297373a894 837 }
mbed_official 579:53297373a894 838 }
mbed_official 579:53297373a894 839
mbed_official 579:53297373a894 840 /************************************
mbed_official 579:53297373a894 841 * TRANSFER FUNCTIONS *
mbed_official 579:53297373a894 842 ***********************************/
mbed_official 579:53297373a894 843 int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint)
mbed_official 579:53297373a894 844 {
mbed_official 592:a274ee790e56 845 /* Sanity check arguments */
mbed_official 592:a274ee790e56 846 MBED_ASSERT(obj);
mbed_official 579:53297373a894 847 MBED_ASSERT(tx != (void*)0);
mbed_official 579:53297373a894 848 if(tx_length == 0) return 0;
mbed_official 579:53297373a894 849
mbed_official 579:53297373a894 850 serial_tx_buffer_set(obj, (void *)tx, tx_length, tx_width);
mbed_official 579:53297373a894 851 serial_tx_enable_event(obj, event, true);
mbed_official 579:53297373a894 852
mbed_official 579:53297373a894 853 // if( hint == DMA_USAGE_NEVER) { //TODO: DMA to be implemented later
mbed_official 579:53297373a894 854 NVIC_ClearPendingIRQ(get_serial_irq_num(obj));
mbed_official 579:53297373a894 855 NVIC_DisableIRQ(get_serial_irq_num(obj));
mbed_official 579:53297373a894 856 NVIC_SetVector(get_serial_irq_num(obj), (uint32_t)handler);
mbed_official 579:53297373a894 857 NVIC_EnableIRQ(get_serial_irq_num(obj));
mbed_official 579:53297373a894 858
mbed_official 579:53297373a894 859 if (pUSART_S(obj)) {
mbed_official 579:53297373a894 860 _USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 579:53297373a894 861 _USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_DRE;
mbed_official 579:53297373a894 862 }
mbed_official 579:53297373a894 863 // }
mbed_official 592:a274ee790e56 864 return 0;
mbed_official 579:53297373a894 865 }
mbed_official 579:53297373a894 866
mbed_official 579:53297373a894 867 void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint)
mbed_official 579:53297373a894 868 {
mbed_official 592:a274ee790e56 869 /* Sanity check arguments */
mbed_official 592:a274ee790e56 870 MBED_ASSERT(obj);
mbed_official 579:53297373a894 871 MBED_ASSERT(rx != (void*)0);
mbed_official 579:53297373a894 872
mbed_official 579:53297373a894 873 serial_rx_enable_event(obj, SERIAL_EVENT_RX_ALL, false);
mbed_official 579:53297373a894 874 serial_rx_enable_event(obj, event, true);
mbed_official 579:53297373a894 875 serial_set_char_match(obj, char_match);
mbed_official 579:53297373a894 876 serial_rx_buffer_set(obj, rx, rx_length, rx_width);
mbed_official 579:53297373a894 877
mbed_official 579:53297373a894 878 // if( hint == DMA_USAGE_NEVER) { //TODO: DMA to be implemented later
mbed_official 579:53297373a894 879 NVIC_ClearPendingIRQ(get_serial_irq_num(obj));
mbed_official 592:a274ee790e56 880 NVIC_DisableIRQ(get_serial_irq_num(obj));
mbed_official 579:53297373a894 881 NVIC_SetVector(get_serial_irq_num(obj), (uint32_t)handler);
mbed_official 579:53297373a894 882 NVIC_EnableIRQ(get_serial_irq_num(obj));
mbed_official 579:53297373a894 883
mbed_official 579:53297373a894 884 if (pUSART_S(obj)) {
mbed_official 579:53297373a894 885 _USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 579:53297373a894 886 }
mbed_official 579:53297373a894 887 // }
mbed_official 592:a274ee790e56 888 return;
mbed_official 579:53297373a894 889 }
mbed_official 579:53297373a894 890
mbed_official 579:53297373a894 891 uint8_t serial_tx_active(serial_t *obj)
mbed_official 579:53297373a894 892 {
mbed_official 592:a274ee790e56 893 /* Sanity check arguments */
mbed_official 592:a274ee790e56 894 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 895 return ((obj->tx_buff.length > 0) ? true : false);
mbed_official 579:53297373a894 896 }
mbed_official 579:53297373a894 897
mbed_official 579:53297373a894 898 uint8_t serial_rx_active(serial_t *obj)
mbed_official 579:53297373a894 899 {
mbed_official 592:a274ee790e56 900 /* Sanity check arguments */
mbed_official 592:a274ee790e56 901 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 902 return ((obj->rx_buff.length > 0) ? true : false);
mbed_official 579:53297373a894 903 }
mbed_official 579:53297373a894 904
mbed_official 579:53297373a894 905 int serial_tx_irq_handler_asynch(serial_t *obj)
mbed_official 579:53297373a894 906 {
mbed_official 592:a274ee790e56 907 /* Sanity check arguments */
mbed_official 592:a274ee790e56 908 MBED_ASSERT(obj);
mbed_official 579:53297373a894 909 _USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 592:a274ee790e56 910 serial_tx_abort_asynch(obj);
mbed_official 579:53297373a894 911 return SERIAL_EVENT_TX_COMPLETE & obj->serial.events;
mbed_official 579:53297373a894 912 }
mbed_official 579:53297373a894 913
mbed_official 579:53297373a894 914 int serial_rx_irq_handler_asynch(serial_t *obj)
mbed_official 579:53297373a894 915 {
mbed_official 592:a274ee790e56 916 /* Sanity check arguments */
mbed_official 592:a274ee790e56 917 MBED_ASSERT(obj);
mbed_official 579:53297373a894 918 int event = 0;
mbed_official 579:53297373a894 919 /* This interrupt handler is called from USART irq */
mbed_official 579:53297373a894 920 uint8_t *buf = (uint8_t*)obj->rx_buff.buffer;
mbed_official 579:53297373a894 921 uint8_t error_code = 0;
mbed_official 579:53297373a894 922 uint16_t received_data = 0;
mbed_official 579:53297373a894 923
mbed_official 579:53297373a894 924 error_code = (uint8_t)(_USART(obj).STATUS.reg & SERCOM_USART_STATUS_MASK);
mbed_official 579:53297373a894 925 /* Check if an error has occurred during the receiving */
mbed_official 579:53297373a894 926 if (error_code) {
mbed_official 579:53297373a894 927 /* Check which error occurred */
mbed_official 579:53297373a894 928 if (error_code & SERCOM_USART_STATUS_FERR) {
mbed_official 579:53297373a894 929 /* Store the error code and clear flag by writing 1 to it */
mbed_official 579:53297373a894 930 _USART(obj).STATUS.reg |= SERCOM_USART_STATUS_FERR;
mbed_official 579:53297373a894 931 return SERIAL_EVENT_RX_FRAMING_ERROR;
mbed_official 579:53297373a894 932 } else if (error_code & SERCOM_USART_STATUS_BUFOVF) {
mbed_official 579:53297373a894 933 /* Store the error code and clear flag by writing 1 to it */
mbed_official 579:53297373a894 934 _USART(obj).STATUS.reg |= SERCOM_USART_STATUS_BUFOVF;
mbed_official 579:53297373a894 935 return SERIAL_EVENT_RX_OVERFLOW;
mbed_official 579:53297373a894 936 } else if (error_code & SERCOM_USART_STATUS_PERR) {
mbed_official 579:53297373a894 937 /* Store the error code and clear flag by writing 1 to it */
mbed_official 579:53297373a894 938 _USART(obj).STATUS.reg |= SERCOM_USART_STATUS_PERR;
mbed_official 579:53297373a894 939 return SERIAL_EVENT_RX_PARITY_ERROR;
mbed_official 579:53297373a894 940 }
mbed_official 579:53297373a894 941 }
mbed_official 579:53297373a894 942
mbed_official 579:53297373a894 943 /* Read current packet from DATA register,
mbed_official 579:53297373a894 944 * increment buffer pointer and decrement buffer length */
mbed_official 579:53297373a894 945 received_data = (_USART(obj).DATA.reg & SERCOM_USART_DATA_MASK);
mbed_official 579:53297373a894 946
mbed_official 579:53297373a894 947 /* Read value will be at least 8-bits long */
mbed_official 579:53297373a894 948 buf[obj->rx_buff.pos] = received_data;
mbed_official 579:53297373a894 949 /* Increment 8-bit pointer */
mbed_official 579:53297373a894 950 obj->rx_buff.pos++;
mbed_official 579:53297373a894 951
mbed_official 579:53297373a894 952 /* Check if the last character have been received */
mbed_official 579:53297373a894 953 if(--(obj->rx_buff.length) == 0) {
mbed_official 579:53297373a894 954 event |= SERIAL_EVENT_RX_COMPLETE;
mbed_official 579:53297373a894 955 if((buf[obj->rx_buff.pos - 1] == obj->char_match) && (obj->serial.events & SERIAL_EVENT_RX_CHARACTER_MATCH)) {
mbed_official 579:53297373a894 956 event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
mbed_official 579:53297373a894 957 }
mbed_official 592:a274ee790e56 958 _USART(obj).INTFLAG.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 579:53297373a894 959 serial_rx_abort_asynch(obj);
mbed_official 579:53297373a894 960 return event & obj->serial.events;
mbed_official 579:53297373a894 961 }
mbed_official 579:53297373a894 962
mbed_official 579:53297373a894 963 /* Check for character match event */
mbed_official 579:53297373a894 964 if((buf[obj->rx_buff.pos - 1] == obj->char_match) && (obj->serial.events & SERIAL_EVENT_RX_CHARACTER_MATCH)) {
mbed_official 579:53297373a894 965 event |= SERIAL_EVENT_RX_CHARACTER_MATCH;
mbed_official 579:53297373a894 966 }
mbed_official 579:53297373a894 967
mbed_official 592:a274ee790e56 968 /* Return to the call back if character match occured */
mbed_official 579:53297373a894 969 if(event != 0) {
mbed_official 579:53297373a894 970 serial_rx_abort_asynch(obj);
mbed_official 579:53297373a894 971 return event & obj->serial.events;
mbed_official 579:53297373a894 972 }
mbed_official 592:a274ee790e56 973 return 0;
mbed_official 579:53297373a894 974 }
mbed_official 579:53297373a894 975
mbed_official 579:53297373a894 976 int serial_irq_handler_asynch(serial_t *obj)
mbed_official 579:53297373a894 977 {
mbed_official 579:53297373a894 978 //TODO: DMA to be implemented
mbed_official 592:a274ee790e56 979 /* Sanity check arguments */
mbed_official 592:a274ee790e56 980 MBED_ASSERT(obj);
mbed_official 579:53297373a894 981 uint16_t interrupt_status;
mbed_official 579:53297373a894 982 uint8_t *buf = obj->tx_buff.buffer;
mbed_official 579:53297373a894 983
mbed_official 579:53297373a894 984 interrupt_status = _USART(obj).INTFLAG.reg;
mbed_official 579:53297373a894 985 interrupt_status &= _USART(obj).INTENSET.reg;
mbed_official 579:53297373a894 986
mbed_official 579:53297373a894 987 if (pUSART_S(obj)) {
mbed_official 579:53297373a894 988 if (interrupt_status & SERCOM_USART_INTFLAG_DRE) {
mbed_official 579:53297373a894 989 /* Interrupt has another TX source */
mbed_official 579:53297373a894 990 if(obj->tx_buff.pos >= obj->tx_buff.length) {
mbed_official 579:53297373a894 991 /* Transfer complete. Switch off interrupt and return event. */
mbed_official 579:53297373a894 992 _USART(obj).INTENCLR.reg = SERCOM_USART_INTFLAG_DRE;
mbed_official 592:a274ee790e56 993 _USART(obj).INTENSET.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 579:53297373a894 994 } else {
mbed_official 579:53297373a894 995 while((serial_writable(obj)) && (obj->tx_buff.pos <= (obj->tx_buff.length - 1))) {
mbed_official 579:53297373a894 996 _USART(obj).DATA.reg = buf[obj->tx_buff.pos];
mbed_official 579:53297373a894 997 obj->tx_buff.pos++;
mbed_official 579:53297373a894 998 }
mbed_official 579:53297373a894 999 }
mbed_official 579:53297373a894 1000 }
mbed_official 579:53297373a894 1001 if (interrupt_status & SERCOM_USART_INTFLAG_TXC) {
mbed_official 592:a274ee790e56 1002 return serial_tx_irq_handler_asynch(obj);
mbed_official 579:53297373a894 1003 }
mbed_official 579:53297373a894 1004 if (interrupt_status & SERCOM_USART_INTFLAG_RXC) {
mbed_official 592:a274ee790e56 1005 return serial_rx_irq_handler_asynch(obj);
mbed_official 579:53297373a894 1006 }
mbed_official 579:53297373a894 1007 }
mbed_official 592:a274ee790e56 1008 return 0;
mbed_official 579:53297373a894 1009 }
mbed_official 579:53297373a894 1010
mbed_official 579:53297373a894 1011 void serial_tx_abort_asynch(serial_t *obj)
mbed_official 579:53297373a894 1012 {
mbed_official 579:53297373a894 1013 //TODO: DMA to be implemented
mbed_official 592:a274ee790e56 1014 /* Sanity check arguments */
mbed_official 592:a274ee790e56 1015 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 1016 _USART(obj).INTFLAG.reg = SERCOM_USART_INTFLAG_TXC;
mbed_official 579:53297373a894 1017 obj->tx_buff.length = 0;
mbed_official 592:a274ee790e56 1018 obj->rx_buff.pos = 0;
mbed_official 592:a274ee790e56 1019
mbed_official 579:53297373a894 1020 }
mbed_official 579:53297373a894 1021
mbed_official 579:53297373a894 1022 void serial_rx_abort_asynch(serial_t *obj)
mbed_official 579:53297373a894 1023 {
mbed_official 579:53297373a894 1024 //TODO: DMA to be implemented
mbed_official 592:a274ee790e56 1025 /* Sanity check arguments */
mbed_official 592:a274ee790e56 1026 MBED_ASSERT(obj);
mbed_official 592:a274ee790e56 1027 _USART(obj).INTFLAG.reg = SERCOM_USART_INTFLAG_RXC;
mbed_official 592:a274ee790e56 1028 obj->rx_buff.length = 0;
mbed_official 579:53297373a894 1029 obj->rx_buff.pos = 0;
mbed_official 579:53297373a894 1030 }
mbed_official 579:53297373a894 1031
mbed_official 579:53297373a894 1032 #endif