added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Mon Nov 09 13:30:11 2015 +0000
Revision:
18:da299f395b9e
Parent:
15:a81a8d6c1dfe
Child:
64:41a834223ea3
Synchronized with git revision f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3

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

Added support for SAML21

Who changed what in which revision?

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