Rigado / mbed-src-bmd-200

Dependents:   mbed_blinky-bmd-200 bmd-200_accel_demo firstRig

Fork of mbed-src by mbed official

Committer:
dcnichols
Date:
Fri Jul 10 17:36:27 2015 +0000
Revision:
592:5e2eb8beba71
Parent:
583:53297373a894
updating to latest mbed-src

Who changed what in which revision?

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