Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

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