Lancaster University's (short term!) clone of mbed-src for micro:bit. This is a copy of the github branch https://github.com/lancaster-university/mbed-classic
Fork of mbed-src by
Diff: common/SerialBase.cpp
- Revision:
- 525:c320967f86b9
- Parent:
- 212:34d62c0b2af6
- Child:
- 563:536c9fb088a0
diff -r c0134becc221 -r c320967f86b9 common/SerialBase.cpp --- a/common/SerialBase.cpp Mon Apr 27 09:45:08 2015 +0100 +++ b/common/SerialBase.cpp Tue Apr 28 11:45:12 2015 +0100 @@ -20,7 +20,12 @@ namespace mbed { -SerialBase::SerialBase(PinName tx, PinName rx) : _serial(), _baud(9600) { +SerialBase::SerialBase(PinName tx, PinName rx) : +#if DEVICE_SERIAL_ASYNCH + _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER), + _rx_usage(DMA_USAGE_NEVER), +#endif + _serial(), _baud(9600) { serial_init(&_serial, tx, rx); serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this); } @@ -103,6 +108,105 @@ } #endif +#if DEVICE_SERIAL_ASYNCH + +int SerialBase::write(uint8_t *buffer, int length, const event_callback_t& callback, int event) +{ + if (serial_tx_active(&_serial)) { + return -1; // transaction ongoing + } + start_write((void *)buffer, length, 8, callback, event); + return 0; +} + +int SerialBase::write(uint16_t *buffer, int length, const event_callback_t& callback, int event) +{ + if (serial_tx_active(&_serial)) { + return -1; // transaction ongoing + } + start_write((void *)buffer, length, 16, callback, event); + return 0; +} + +void SerialBase::start_write(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event) +{ + _tx_callback = callback; + + _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); + serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage); +} + +void SerialBase::abort_write(void) +{ + serial_tx_abort_asynch(&_serial); +} + +void SerialBase::abort_read(void) +{ + serial_rx_abort_asynch(&_serial); +} + +int SerialBase::set_dma_usage_tx(DMAUsage usage) +{ + if (serial_tx_active(&_serial)) { + return -1; + } + _tx_usage = usage; + return 0; +} + +int SerialBase::set_dma_usage_rx(DMAUsage usage) +{ + if (serial_tx_active(&_serial)) { + return -1; + } + _rx_usage = usage; + return 0; +} + +int SerialBase::read(uint8_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) +{ + if (serial_rx_active(&_serial)) { + return -1; // transaction ongoing + } + start_read((void*)buffer, length, 8, callback, event, char_match); + return 0; +} + + +int SerialBase::read(uint16_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match) +{ + if (serial_rx_active(&_serial)) { + return -1; // transaction ongoing + } + start_read((void*)buffer, length, 16, callback, event, char_match); + return 0; +} + + +void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match) +{ + _rx_callback = callback; + _thunk_irq.callback(&SerialBase::interrupt_handler_asynch); + serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage); +} + +void SerialBase::interrupt_handler_asynch(void) +{ + int event = serial_irq_handler_asynch(&_serial); + int rx_event = event & SERIAL_EVENT_RX_MASK; + if (_rx_callback && rx_event) { + _rx_callback.call(rx_event); + } + + int tx_event = event & SERIAL_EVENT_TX_MASK; + if (_tx_callback && tx_event) { + _tx_callback.call(tx_event); + } +} + +#endif + } // namespace mbed #endif