added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Wed Nov 04 16:30:11 2015 +0000
Revision:
15:a81a8d6c1dfe
Child:
18:da299f395b9e
Synchronized with git revision 46af745ef4405614c3fa49abbd9a706a362ea514

Full URL: https://github.com/mbedmicro/mbed/commit/46af745ef4405614c3fa49abbd9a706a362ea514/

Renamed TARGET_SAM_CortexM0+ to TARGET_SAM_CortexM0P for compatiblity with online compiler

Who changed what in which revision?

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