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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo 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 "SerialBase.h" 00017 #include "wait_api.h" 00018 #include "critical.h" 00019 00020 #if DEVICE_SERIAL 00021 00022 namespace mbed { 00023 00024 static void donothing() {}; 00025 00026 SerialBase::SerialBase(PinName tx, PinName rx) : 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(9600) { 00032 // No lock needed in the constructor 00033 00034 for (int i = 0; i < sizeof _irq / sizeof _irq[0]; i++) { 00035 _irq[i].attach(donothing); 00036 } 00037 00038 serial_init(&_serial, tx, rx); 00039 serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this); 00040 } 00041 00042 void SerialBase::baud(int baudrate) { 00043 lock(); 00044 serial_baud(&_serial, baudrate); 00045 _baud = baudrate; 00046 unlock(); 00047 } 00048 00049 void SerialBase::format(int bits, Parity parity, int stop_bits) { 00050 lock(); 00051 serial_format(&_serial, bits, (SerialParity)parity, stop_bits); 00052 unlock(); 00053 } 00054 00055 int SerialBase::readable() { 00056 lock(); 00057 int ret = serial_readable(&_serial); 00058 unlock(); 00059 return ret; 00060 } 00061 00062 00063 int SerialBase::writeable() { 00064 lock(); 00065 int ret = serial_writable(&_serial); 00066 unlock(); 00067 return ret; 00068 } 00069 00070 void SerialBase::attach(Callback<void()> func, IrqType type) { 00071 lock(); 00072 // Disable interrupts when attaching interrupt handler 00073 core_util_critical_section_enter(); 00074 if (func) { 00075 _irq[type].attach(func); 00076 serial_irq_set(&_serial, (SerialIrq)type, 1); 00077 } else { 00078 _irq[type].attach(donothing); 00079 serial_irq_set(&_serial, (SerialIrq)type, 0); 00080 } 00081 core_util_critical_section_exit(); 00082 unlock(); 00083 } 00084 00085 void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) { 00086 SerialBase *handler = (SerialBase*)id; 00087 handler->_irq[irq_type].call(); 00088 } 00089 00090 int SerialBase::_base_getc() { 00091 // Mutex is already held 00092 return serial_getc(&_serial); 00093 } 00094 00095 int SerialBase::_base_putc(int c) { 00096 // Mutex is already held 00097 serial_putc(&_serial, c); 00098 return c; 00099 } 00100 00101 void SerialBase::send_break() { 00102 lock(); 00103 // Wait for 1.5 frames before clearing the break condition 00104 // This will have different effects on our platforms, but should 00105 // ensure that we keep the break active for at least one frame. 00106 // We consider a full frame (1 start bit + 8 data bits bits + 00107 // 1 parity bit + 2 stop bits = 12 bits) for computation. 00108 // One bit time (in us) = 1000000/_baud 00109 // Twelve bits: 12000000/baud delay 00110 // 1.5 frames: 18000000/baud delay 00111 serial_break_set(&_serial); 00112 wait_us(18000000/_baud); 00113 serial_break_clear(&_serial); 00114 unlock(); 00115 } 00116 00117 void SerialBase::lock() { 00118 // Stub 00119 } 00120 00121 void SerialBase:: unlock() { 00122 // Stub 00123 } 00124 00125 #if DEVICE_SERIAL_FC 00126 void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) { 00127 lock(); 00128 FlowControl flow_type = (FlowControl)type; 00129 switch(type) { 00130 case RTS: 00131 serial_set_flow_control(&_serial, flow_type, flow1, NC); 00132 break; 00133 00134 case CTS: 00135 serial_set_flow_control(&_serial, flow_type, NC, flow1); 00136 break; 00137 00138 case RTSCTS: 00139 case Disabled: 00140 serial_set_flow_control(&_serial, flow_type, flow1, flow2); 00141 break; 00142 00143 default: 00144 break; 00145 } 00146 unlock(); 00147 } 00148 #endif 00149 00150 #if DEVICE_SERIAL_ASYNCH 00151 00152 int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t& callback, int event) 00153 { 00154 if (serial_tx_active(&_serial)) { 00155 return -1; // transaction ongoing 00156 } 00157 start_write((void *)buffer, length, 8, callback, event); 00158 return 0; 00159 } 00160 00161 int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t& callback, int event) 00162 { 00163 if (serial_tx_active(&_serial)) { 00164 return -1; // transaction ongoing 00165 } 00166 start_write((void *)buffer, length, 16, callback, event); 00167 return 0; 00168 } 00169 00170 void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event) 00171 { 00172 _tx_callback = callback; 00173 00174 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00175 serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage); 00176 } 00177 00178 void SerialBase::abort_write(void) 00179 { 00180 serial_tx_abort_asynch(&_serial); 00181 } 00182 00183 void SerialBase::abort_read(void) 00184 { 00185 serial_rx_abort_asynch(&_serial); 00186 } 00187 00188 int SerialBase::set_dma_usage_tx(DMAUsage usage) 00189 { 00190 if (serial_tx_active(&_serial)) { 00191 return -1; 00192 } 00193 _tx_usage = usage; 00194 return 0; 00195 } 00196 00197 int SerialBase::set_dma_usage_rx(DMAUsage usage) 00198 { 00199 if (serial_tx_active(&_serial)) { 00200 return -1; 00201 } 00202 _rx_usage = usage; 00203 return 0; 00204 } 00205 00206 int SerialBase::read(uint8_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) 00207 { 00208 if (serial_rx_active(&_serial)) { 00209 return -1; // transaction ongoing 00210 } 00211 start_read((void*)buffer, length, 8, callback, event, char_match); 00212 return 0; 00213 } 00214 00215 00216 int SerialBase::read(uint16_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) 00217 { 00218 if (serial_rx_active(&_serial)) { 00219 return -1; // transaction ongoing 00220 } 00221 start_read((void*)buffer, length, 16, callback, event, char_match); 00222 return 0; 00223 } 00224 00225 00226 void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match) 00227 { 00228 _rx_callback = callback; 00229 _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); 00230 serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage); 00231 } 00232 00233 void SerialBase::interrupt_handler_asynch(void) 00234 { 00235 int event = serial_irq_handler_asynch(&_serial); 00236 int rx_event = event & SERIAL_EVENT_RX_MASK; 00237 if (_rx_callback && rx_event) { 00238 _rx_callback.call(rx_event); 00239 } 00240 00241 int tx_event = event & SERIAL_EVENT_TX_MASK; 00242 if (_tx_callback && tx_event) { 00243 _tx_callback.call(tx_event); 00244 } 00245 } 00246 00247 #endif 00248 00249 } // namespace mbed 00250 00251 #endif
Generated on Tue Jul 12 2022 12:28:48 by
