Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

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