Rahul Dahiya / Mbed OS STM32F7 Ethernet
Committer:
rahul_dahiya
Date:
Wed Jan 15 15:57:15 2020 +0530
Revision:
0:fb8047b156bb
STM32F7 LWIP

Who changed what in which revision?

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