Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TUKS-COURSE-TIMER by
SerialBase.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "drivers/SerialBase.h" 00017 #include "platform/wait_api.h" 00018 #include "platform/critical.h" 00019 00020 #if DEVICE_SERIAL 00021 00022 namespace mbed { 00023 00024 static void donothing() {}; 00025 00026 SerialBase::SerialBase(PinName tx, PinName rx, int baud) : 00027 #if DEVICE_SERIAL_ASYNCH 00028 _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER), 00029 _rx_usage(DMA_USAGE_NEVER), 00030 #endif 00031 _serial(), _baud(baud) { 00032 // No lock needed in the constructor 00033 00034 for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) { 00035 _irq[i].attach(donothing); 00036 } 00037 00038 serial_init(&_serial, tx, rx); 00039 serial_baud(&_serial, _baud); 00040 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this); 00041 } 00042 00043 void SerialBase::baud(int baudrate) { 00044 lock(); 00045 serial_baud(&_serial, baudrate); 00046 _baud = baudrate; 00047 unlock(); 00048 } 00049 00050 void SerialBase::format(int bits, Parity parity, int stop_bits) { 00051 lock(); 00052 serial_format(&_serial, bits, (SerialParity)parity, stop_bits); 00053 unlock(); 00054 } 00055 00056 int SerialBase::readable() { 00057 lock(); 00058 int ret = serial_readable(&_serial); 00059 unlock(); 00060 return ret; 00061 } 00062 00063 00064 int SerialBase::writeable() { 00065 lock(); 00066 int ret = serial_writable(&_serial); 00067 unlock(); 00068 return ret; 00069 } 00070 00071 void SerialBase::attach(Callback<void()> func, IrqType type) { 00072 lock(); 00073 // Disable interrupts when attaching interrupt handler 00074 core_util_critical_section_enter(); 00075 if (func) { 00076 _irq[type].attach(func); 00077 serial_irq_set(&_serial, (SerialIrq)type, 1); 00078 } else { 00079 _irq[type].attach(donothing); 00080 serial_irq_set(&_serial, (SerialIrq)type, 0); 00081 } 00082 core_util_critical_section_exit(); 00083 unlock(); 00084 } 00085 00086 void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) { 00087 SerialBase *handler = (SerialBase*)id; 00088 handler->_irq[irq_type].call(); 00089 } 00090 00091 int SerialBase::_base_getc() { 00092 // Mutex is already held 00093 return serial_getc(&_serial); 00094 } 00095 00096 int SerialBase::_base_putc(int c) { 00097 // Mutex is already held 00098 serial_putc(&_serial, c); 00099 return c; 00100 } 00101 00102 void SerialBase::send_break() { 00103 lock(); 00104 // Wait for 1.5 frames before clearing the break condition 00105 // This will have different effects on our platforms, but should 00106 // ensure that we keep the break active for at least one frame. 00107 // We consider a full frame (1 start bit + 8 data bits bits + 00108 // 1 parity bit + 2 stop bits = 12 bits) for computation. 00109 // One bit time (in us) = 1000000/_baud 00110 // Twelve bits: 12000000/baud delay 00111 // 1.5 frames: 18000000/baud delay 00112 serial_break_set(&_serial); 00113 wait_us(18000000/_baud); 00114 serial_break_clear(&_serial); 00115 unlock(); 00116 } 00117 00118 void SerialBase::lock() { 00119 // Stub 00120 } 00121 00122 void SerialBase:: unlock() { 00123 // Stub 00124 } 00125 00126 #if DEVICE_SERIAL_FC 00127 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) { 00128 lock(); 00129 FlowControl flow_type = (FlowControl)type; 00130 switch(type) { 00131 case RTS: 00132 serial_set_flow_control(&_serial, flow_type, flow1, NC); 00133 break; 00134 00135 case CTS: 00136 serial_set_flow_control(&_serial, flow_type, NC, flow1); 00137 break; 00138 00139 case RTSCTS: 00140 case Disabled: 00141 serial_set_flow_control(&_serial, flow_type, flow1, flow2); 00142 break; 00143 00144 default: 00145 break; 00146 } 00147 unlock(); 00148 } 00149 #endif 00150 00151 #if DEVICE_SERIAL_ASYNCH 00152 00153 int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t& callback, int event) 00154 { 00155 if (serial_tx_active(&_serial)) { 00156 return -1; // transaction ongoing 00157 } 00158 start_write((void *)buffer, length, 8, callback, event); 00159 return 0; 00160 } 00161 00162 int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t& callback, int event) 00163 { 00164 if (serial_tx_active(&_serial)) { 00165 return -1; // transaction ongoing 00166 } 00167 start_write((void *)buffer, length, 16, callback, event); 00168 return 0; 00169 } 00170 00171 void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event) 00172 { 00173 _tx_callback = callback; 00174 00175 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00176 serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage); 00177 } 00178 00179 void SerialBase::abort_write(void) 00180 { 00181 serial_tx_abort_asynch(&_serial); 00182 } 00183 00184 void SerialBase::abort_read(void) 00185 { 00186 serial_rx_abort_asynch(&_serial); 00187 } 00188 00189 int SerialBase::set_dma_usage_tx(DMAUsage usage) 00190 { 00191 if (serial_tx_active(&_serial)) { 00192 return -1; 00193 } 00194 _tx_usage = usage; 00195 return 0; 00196 } 00197 00198 int SerialBase::set_dma_usage_rx(DMAUsage usage) 00199 { 00200 if (serial_tx_active(&_serial)) { 00201 return -1; 00202 } 00203 _rx_usage = usage; 00204 return 0; 00205 } 00206 00207 int SerialBase::read(uint8_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) 00208 { 00209 if (serial_rx_active(&_serial)) { 00210 return -1; // transaction ongoing 00211 } 00212 start_read((void*)buffer, length, 8, callback, event, char_match); 00213 return 0; 00214 } 00215 00216 00217 int SerialBase::read(uint16_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) 00218 { 00219 if (serial_rx_active(&_serial)) { 00220 return -1; // transaction ongoing 00221 } 00222 start_read((void*)buffer, length, 16, callback, event, char_match); 00223 return 0; 00224 } 00225 00226 00227 void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match) 00228 { 00229 _rx_callback = callback; 00230 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00231 serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage); 00232 } 00233 00234 void SerialBase::interrupt_handler_asynch(void) 00235 { 00236 int event = serial_irq_handler_asynch(&_serial); 00237 int rx_event = event & SERIAL_EVENT_RX_MASK; 00238 if (_rx_callback && rx_event) { 00239 _rx_callback.call(rx_event); 00240 } 00241 00242 int tx_event = event & SERIAL_EVENT_TX_MASK; 00243 if (_tx_callback && tx_event) { 00244 _tx_callback.call(tx_event); 00245 } 00246 } 00247 00248 #endif 00249 00250 } // namespace mbed 00251 00252 #endif
Generated on Tue Jul 12 2022 17:38:48 by
