This is the final version of Mini Gateway for Automation and Security desgined for Renesas GR Peach Design Contest

Dependencies:   GR-PEACH_video GraphicsFramework HTTPServer R_BSP mbed-rpc mbed-rtos Socket lwip-eth lwip-sys lwip FATFileSystem

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SerialBase.cpp Source File

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