added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Mon Feb 15 10:00:10 2016 +0000
Revision:
64:41a834223ea3
Parent:
18:da299f395b9e
Synchronized with git revision e641fd47cf2a6bafdbe87c743a39772f73edcbe7

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

Fixed GCC Compiler warnings

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