Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 0:6c56fb4bc5f0 1 /* mbed Microcontroller Library
nexpaq 0:6c56fb4bc5f0 2 * Copyright (c) 2006-2013 ARM Limited
nexpaq 0:6c56fb4bc5f0 3 *
nexpaq 0:6c56fb4bc5f0 4 * Licensed under the Apache License, Version 2.0 (the "License");
nexpaq 0:6c56fb4bc5f0 5 * you may not use this file except in compliance with the License.
nexpaq 0:6c56fb4bc5f0 6 * You may obtain a copy of the License at
nexpaq 0:6c56fb4bc5f0 7 *
nexpaq 0:6c56fb4bc5f0 8 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 0:6c56fb4bc5f0 9 *
nexpaq 0:6c56fb4bc5f0 10 * Unless required by applicable law or agreed to in writing, software
nexpaq 0:6c56fb4bc5f0 11 * distributed under the License is distributed on an "AS IS" BASIS,
nexpaq 0:6c56fb4bc5f0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 0:6c56fb4bc5f0 13 * See the License for the specific language governing permissions and
nexpaq 0:6c56fb4bc5f0 14 * limitations under the License.
nexpaq 0:6c56fb4bc5f0 15 */
nexpaq 0:6c56fb4bc5f0 16 #include "SerialBase.h"
nexpaq 0:6c56fb4bc5f0 17 #include "wait_api.h"
nexpaq 0:6c56fb4bc5f0 18 #include "critical.h"
nexpaq 0:6c56fb4bc5f0 19
nexpaq 0:6c56fb4bc5f0 20 #if DEVICE_SERIAL
nexpaq 0:6c56fb4bc5f0 21
nexpaq 0:6c56fb4bc5f0 22 namespace mbed {
nexpaq 0:6c56fb4bc5f0 23
nexpaq 0:6c56fb4bc5f0 24 static void donothing() {};
nexpaq 0:6c56fb4bc5f0 25
nexpaq 0:6c56fb4bc5f0 26 SerialBase::SerialBase(PinName tx, PinName rx) :
nexpaq 0:6c56fb4bc5f0 27 #if DEVICE_SERIAL_ASYNCH
nexpaq 0:6c56fb4bc5f0 28 _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER),
nexpaq 0:6c56fb4bc5f0 29 _rx_usage(DMA_USAGE_NEVER),
nexpaq 0:6c56fb4bc5f0 30 #endif
nexpaq 0:6c56fb4bc5f0 31 _serial(), _baud(9600) {
nexpaq 0:6c56fb4bc5f0 32 // No lock needed in the constructor
nexpaq 0:6c56fb4bc5f0 33
nexpaq 0:6c56fb4bc5f0 34 for (int i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
nexpaq 0:6c56fb4bc5f0 35 _irq[i].attach(donothing);
nexpaq 0:6c56fb4bc5f0 36 }
nexpaq 0:6c56fb4bc5f0 37
nexpaq 0:6c56fb4bc5f0 38 serial_init(&_serial, tx, rx);
nexpaq 0:6c56fb4bc5f0 39 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
nexpaq 0:6c56fb4bc5f0 40 }
nexpaq 0:6c56fb4bc5f0 41
nexpaq 0:6c56fb4bc5f0 42 void SerialBase::baud(int baudrate) {
nexpaq 0:6c56fb4bc5f0 43 lock();
nexpaq 0:6c56fb4bc5f0 44 serial_baud(&_serial, baudrate);
nexpaq 0:6c56fb4bc5f0 45 _baud = baudrate;
nexpaq 0:6c56fb4bc5f0 46 unlock();
nexpaq 0:6c56fb4bc5f0 47 }
nexpaq 0:6c56fb4bc5f0 48
nexpaq 0:6c56fb4bc5f0 49 void SerialBase::format(int bits, Parity parity, int stop_bits) {
nexpaq 0:6c56fb4bc5f0 50 lock();
nexpaq 0:6c56fb4bc5f0 51 serial_format(&_serial, bits, (SerialParity)parity, stop_bits);
nexpaq 0:6c56fb4bc5f0 52 unlock();
nexpaq 0:6c56fb4bc5f0 53 }
nexpaq 0:6c56fb4bc5f0 54
nexpaq 0:6c56fb4bc5f0 55 int SerialBase::readable() {
nexpaq 0:6c56fb4bc5f0 56 lock();
nexpaq 0:6c56fb4bc5f0 57 int ret = serial_readable(&_serial);
nexpaq 0:6c56fb4bc5f0 58 unlock();
nexpaq 0:6c56fb4bc5f0 59 return ret;
nexpaq 0:6c56fb4bc5f0 60 }
nexpaq 0:6c56fb4bc5f0 61
nexpaq 0:6c56fb4bc5f0 62
nexpaq 0:6c56fb4bc5f0 63 int SerialBase::writeable() {
nexpaq 0:6c56fb4bc5f0 64 lock();
nexpaq 0:6c56fb4bc5f0 65 int ret = serial_writable(&_serial);
nexpaq 0:6c56fb4bc5f0 66 unlock();
nexpaq 0:6c56fb4bc5f0 67 return ret;
nexpaq 0:6c56fb4bc5f0 68 }
nexpaq 0:6c56fb4bc5f0 69
nexpaq 0:6c56fb4bc5f0 70 void SerialBase::attach(Callback<void()> func, IrqType type) {
nexpaq 0:6c56fb4bc5f0 71 lock();
nexpaq 0:6c56fb4bc5f0 72 // Disable interrupts when attaching interrupt handler
nexpaq 0:6c56fb4bc5f0 73 core_util_critical_section_enter();
nexpaq 0:6c56fb4bc5f0 74 if (func) {
nexpaq 0:6c56fb4bc5f0 75 _irq[type].attach(func);
nexpaq 0:6c56fb4bc5f0 76 serial_irq_set(&_serial, (SerialIrq)type, 1);
nexpaq 0:6c56fb4bc5f0 77 } else {
nexpaq 0:6c56fb4bc5f0 78 _irq[type].attach(donothing);
nexpaq 0:6c56fb4bc5f0 79 serial_irq_set(&_serial, (SerialIrq)type, 0);
nexpaq 0:6c56fb4bc5f0 80 }
nexpaq 0:6c56fb4bc5f0 81 core_util_critical_section_exit();
nexpaq 0:6c56fb4bc5f0 82 unlock();
nexpaq 0:6c56fb4bc5f0 83 }
nexpaq 0:6c56fb4bc5f0 84
nexpaq 0:6c56fb4bc5f0 85 void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) {
nexpaq 0:6c56fb4bc5f0 86 SerialBase *handler = (SerialBase*)id;
nexpaq 0:6c56fb4bc5f0 87 handler->_irq[irq_type].call();
nexpaq 0:6c56fb4bc5f0 88 }
nexpaq 0:6c56fb4bc5f0 89
nexpaq 0:6c56fb4bc5f0 90 int SerialBase::_base_getc() {
nexpaq 0:6c56fb4bc5f0 91 // Mutex is already held
nexpaq 0:6c56fb4bc5f0 92 return serial_getc(&_serial);
nexpaq 0:6c56fb4bc5f0 93 }
nexpaq 0:6c56fb4bc5f0 94
nexpaq 0:6c56fb4bc5f0 95 int SerialBase::_base_putc(int c) {
nexpaq 0:6c56fb4bc5f0 96 // Mutex is already held
nexpaq 0:6c56fb4bc5f0 97 serial_putc(&_serial, c);
nexpaq 0:6c56fb4bc5f0 98 return c;
nexpaq 0:6c56fb4bc5f0 99 }
nexpaq 0:6c56fb4bc5f0 100
nexpaq 0:6c56fb4bc5f0 101 void SerialBase::send_break() {
nexpaq 0:6c56fb4bc5f0 102 lock();
nexpaq 0:6c56fb4bc5f0 103 // Wait for 1.5 frames before clearing the break condition
nexpaq 0:6c56fb4bc5f0 104 // This will have different effects on our platforms, but should
nexpaq 0:6c56fb4bc5f0 105 // ensure that we keep the break active for at least one frame.
nexpaq 0:6c56fb4bc5f0 106 // We consider a full frame (1 start bit + 8 data bits bits +
nexpaq 0:6c56fb4bc5f0 107 // 1 parity bit + 2 stop bits = 12 bits) for computation.
nexpaq 0:6c56fb4bc5f0 108 // One bit time (in us) = 1000000/_baud
nexpaq 0:6c56fb4bc5f0 109 // Twelve bits: 12000000/baud delay
nexpaq 0:6c56fb4bc5f0 110 // 1.5 frames: 18000000/baud delay
nexpaq 0:6c56fb4bc5f0 111 serial_break_set(&_serial);
nexpaq 0:6c56fb4bc5f0 112 wait_us(18000000/_baud);
nexpaq 0:6c56fb4bc5f0 113 serial_break_clear(&_serial);
nexpaq 0:6c56fb4bc5f0 114 unlock();
nexpaq 0:6c56fb4bc5f0 115 }
nexpaq 0:6c56fb4bc5f0 116
nexpaq 0:6c56fb4bc5f0 117 void SerialBase::lock() {
nexpaq 0:6c56fb4bc5f0 118 // Stub
nexpaq 0:6c56fb4bc5f0 119 }
nexpaq 0:6c56fb4bc5f0 120
nexpaq 0:6c56fb4bc5f0 121 void SerialBase:: unlock() {
nexpaq 0:6c56fb4bc5f0 122 // Stub
nexpaq 0:6c56fb4bc5f0 123 }
nexpaq 0:6c56fb4bc5f0 124
nexpaq 0:6c56fb4bc5f0 125 #if DEVICE_SERIAL_FC
nexpaq 0:6c56fb4bc5f0 126 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) {
nexpaq 0:6c56fb4bc5f0 127 lock();
nexpaq 0:6c56fb4bc5f0 128 FlowControl flow_type = (FlowControl)type;
nexpaq 0:6c56fb4bc5f0 129 switch(type) {
nexpaq 0:6c56fb4bc5f0 130 case RTS:
nexpaq 0:6c56fb4bc5f0 131 serial_set_flow_control(&_serial, flow_type, flow1, NC);
nexpaq 0:6c56fb4bc5f0 132 break;
nexpaq 0:6c56fb4bc5f0 133
nexpaq 0:6c56fb4bc5f0 134 case CTS:
nexpaq 0:6c56fb4bc5f0 135 serial_set_flow_control(&_serial, flow_type, NC, flow1);
nexpaq 0:6c56fb4bc5f0 136 break;
nexpaq 0:6c56fb4bc5f0 137
nexpaq 0:6c56fb4bc5f0 138 case RTSCTS:
nexpaq 0:6c56fb4bc5f0 139 case Disabled:
nexpaq 0:6c56fb4bc5f0 140 serial_set_flow_control(&_serial, flow_type, flow1, flow2);
nexpaq 0:6c56fb4bc5f0 141 break;
nexpaq 0:6c56fb4bc5f0 142
nexpaq 0:6c56fb4bc5f0 143 default:
nexpaq 0:6c56fb4bc5f0 144 break;
nexpaq 0:6c56fb4bc5f0 145 }
nexpaq 0:6c56fb4bc5f0 146 unlock();
nexpaq 0:6c56fb4bc5f0 147 }
nexpaq 0:6c56fb4bc5f0 148 #endif
nexpaq 0:6c56fb4bc5f0 149
nexpaq 0:6c56fb4bc5f0 150 #if DEVICE_SERIAL_ASYNCH
nexpaq 0:6c56fb4bc5f0 151
nexpaq 0:6c56fb4bc5f0 152 int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t& callback, int event)
nexpaq 0:6c56fb4bc5f0 153 {
nexpaq 0:6c56fb4bc5f0 154 if (serial_tx_active(&_serial)) {
nexpaq 0:6c56fb4bc5f0 155 return -1; // transaction ongoing
nexpaq 0:6c56fb4bc5f0 156 }
nexpaq 0:6c56fb4bc5f0 157 start_write((void *)buffer, length, 8, callback, event);
nexpaq 0:6c56fb4bc5f0 158 return 0;
nexpaq 0:6c56fb4bc5f0 159 }
nexpaq 0:6c56fb4bc5f0 160
nexpaq 0:6c56fb4bc5f0 161 int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t& callback, int event)
nexpaq 0:6c56fb4bc5f0 162 {
nexpaq 0:6c56fb4bc5f0 163 if (serial_tx_active(&_serial)) {
nexpaq 0:6c56fb4bc5f0 164 return -1; // transaction ongoing
nexpaq 0:6c56fb4bc5f0 165 }
nexpaq 0:6c56fb4bc5f0 166 start_write((void *)buffer, length, 16, callback, event);
nexpaq 0:6c56fb4bc5f0 167 return 0;
nexpaq 0:6c56fb4bc5f0 168 }
nexpaq 0:6c56fb4bc5f0 169
nexpaq 0:6c56fb4bc5f0 170 void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event)
nexpaq 0:6c56fb4bc5f0 171 {
nexpaq 0:6c56fb4bc5f0 172 _tx_callback = callback;
nexpaq 0:6c56fb4bc5f0 173
nexpaq 0:6c56fb4bc5f0 174 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
nexpaq 0:6c56fb4bc5f0 175 serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage);
nexpaq 0:6c56fb4bc5f0 176 }
nexpaq 0:6c56fb4bc5f0 177
nexpaq 0:6c56fb4bc5f0 178 void SerialBase::abort_write(void)
nexpaq 0:6c56fb4bc5f0 179 {
nexpaq 0:6c56fb4bc5f0 180 serial_tx_abort_asynch(&_serial);
nexpaq 0:6c56fb4bc5f0 181 }
nexpaq 0:6c56fb4bc5f0 182
nexpaq 0:6c56fb4bc5f0 183 void SerialBase::abort_read(void)
nexpaq 0:6c56fb4bc5f0 184 {
nexpaq 0:6c56fb4bc5f0 185 serial_rx_abort_asynch(&_serial);
nexpaq 0:6c56fb4bc5f0 186 }
nexpaq 0:6c56fb4bc5f0 187
nexpaq 0:6c56fb4bc5f0 188 int SerialBase::set_dma_usage_tx(DMAUsage usage)
nexpaq 0:6c56fb4bc5f0 189 {
nexpaq 0:6c56fb4bc5f0 190 if (serial_tx_active(&_serial)) {
nexpaq 0:6c56fb4bc5f0 191 return -1;
nexpaq 0:6c56fb4bc5f0 192 }
nexpaq 0:6c56fb4bc5f0 193 _tx_usage = usage;
nexpaq 0:6c56fb4bc5f0 194 return 0;
nexpaq 0:6c56fb4bc5f0 195 }
nexpaq 0:6c56fb4bc5f0 196
nexpaq 0:6c56fb4bc5f0 197 int SerialBase::set_dma_usage_rx(DMAUsage usage)
nexpaq 0:6c56fb4bc5f0 198 {
nexpaq 0:6c56fb4bc5f0 199 if (serial_tx_active(&_serial)) {
nexpaq 0:6c56fb4bc5f0 200 return -1;
nexpaq 0:6c56fb4bc5f0 201 }
nexpaq 0:6c56fb4bc5f0 202 _rx_usage = usage;
nexpaq 0:6c56fb4bc5f0 203 return 0;
nexpaq 0:6c56fb4bc5f0 204 }
nexpaq 0:6c56fb4bc5f0 205
nexpaq 0:6c56fb4bc5f0 206 int SerialBase::read(uint8_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match)
nexpaq 0:6c56fb4bc5f0 207 {
nexpaq 0:6c56fb4bc5f0 208 if (serial_rx_active(&_serial)) {
nexpaq 0:6c56fb4bc5f0 209 return -1; // transaction ongoing
nexpaq 0:6c56fb4bc5f0 210 }
nexpaq 0:6c56fb4bc5f0 211 start_read((void*)buffer, length, 8, callback, event, char_match);
nexpaq 0:6c56fb4bc5f0 212 return 0;
nexpaq 0:6c56fb4bc5f0 213 }
nexpaq 0:6c56fb4bc5f0 214
nexpaq 0:6c56fb4bc5f0 215
nexpaq 0:6c56fb4bc5f0 216 int SerialBase::read(uint16_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match)
nexpaq 0:6c56fb4bc5f0 217 {
nexpaq 0:6c56fb4bc5f0 218 if (serial_rx_active(&_serial)) {
nexpaq 0:6c56fb4bc5f0 219 return -1; // transaction ongoing
nexpaq 0:6c56fb4bc5f0 220 }
nexpaq 0:6c56fb4bc5f0 221 start_read((void*)buffer, length, 16, callback, event, char_match);
nexpaq 0:6c56fb4bc5f0 222 return 0;
nexpaq 0:6c56fb4bc5f0 223 }
nexpaq 0:6c56fb4bc5f0 224
nexpaq 0:6c56fb4bc5f0 225
nexpaq 0:6c56fb4bc5f0 226 void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match)
nexpaq 0:6c56fb4bc5f0 227 {
nexpaq 0:6c56fb4bc5f0 228 _rx_callback = callback;
nexpaq 0:6c56fb4bc5f0 229 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
nexpaq 0:6c56fb4bc5f0 230 serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage);
nexpaq 0:6c56fb4bc5f0 231 }
nexpaq 0:6c56fb4bc5f0 232
nexpaq 0:6c56fb4bc5f0 233 void SerialBase::interrupt_handler_asynch(void)
nexpaq 0:6c56fb4bc5f0 234 {
nexpaq 0:6c56fb4bc5f0 235 int event = serial_irq_handler_asynch(&_serial);
nexpaq 0:6c56fb4bc5f0 236 int rx_event = event & SERIAL_EVENT_RX_MASK;
nexpaq 0:6c56fb4bc5f0 237 if (_rx_callback && rx_event) {
nexpaq 0:6c56fb4bc5f0 238 _rx_callback.call(rx_event);
nexpaq 0:6c56fb4bc5f0 239 }
nexpaq 0:6c56fb4bc5f0 240
nexpaq 0:6c56fb4bc5f0 241 int tx_event = event & SERIAL_EVENT_TX_MASK;
nexpaq 0:6c56fb4bc5f0 242 if (_tx_callback && tx_event) {
nexpaq 0:6c56fb4bc5f0 243 _tx_callback.call(tx_event);
nexpaq 0:6c56fb4bc5f0 244 }
nexpaq 0:6c56fb4bc5f0 245 }
nexpaq 0:6c56fb4bc5f0 246
nexpaq 0:6c56fb4bc5f0 247 #endif
nexpaq 0:6c56fb4bc5f0 248
nexpaq 0:6c56fb4bc5f0 249 } // namespace mbed
nexpaq 0:6c56fb4bc5f0 250
nexpaq 0:6c56fb4bc5f0 251 #endif