added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
64:41a834223ea3
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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