sf
Fork of mbed-stm32l0l1-src-1 by
Diff: common/SPI.cpp
- Revision:
- 639:b32fded6b0ae
- Parent:
- 638:56887a2974b9
--- a/common/SPI.cpp Thu Sep 08 02:46:37 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "SPI.h" - -#if DEVICE_SPI - -namespace mbed { - -#if DEVICE_SPI_ASYNCH && TRANSACTION_QUEUE_SIZE_SPI -CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> SPI::_transaction_buffer; -#endif - -SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) : - _spi(), -#if DEVICE_SPI_ASYNCH - _irq(this), - _usage(DMA_USAGE_NEVER), -#endif - _bits(8), - _mode(0), - _hz(1000000) { - spi_init(&_spi, mosi, miso, sclk, ssel); - spi_format(&_spi, _bits, _mode, 0); - spi_frequency(&_spi, _hz); -} - -void SPI::format(int bits, int mode) { - _bits = bits; - _mode = mode; - SPI::_owner = NULL; // Not that elegant, but works. rmeyer - aquire(); -} - -void SPI::frequency(int hz) { - _hz = hz; - SPI::_owner = NULL; // Not that elegant, but works. rmeyer - aquire(); -} - -SPI* SPI::_owner = NULL; - -// ignore the fact there are multiple physical spis, and always update if it wasnt us last -void SPI::aquire() { - if (_owner != this) { - spi_format(&_spi, _bits, _mode, 0); - spi_frequency(&_spi, _hz); - _owner = this; - } -} - -int SPI::write(int value) { - aquire(); - return spi_master_write(&_spi, value); -} - -#if DEVICE_SPI_ASYNCH - -int SPI::transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event) -{ - if (spi_active(&_spi)) { - return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event); - } - start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event); - return 0; -} - -void SPI::abort_transfer() -{ - spi_abort_asynch(&_spi); -#if TRANSACTION_QUEUE_SIZE_SPI - dequeue_transaction(); -#endif -} - - -void SPI::clear_transfer_buffer() -{ -#if TRANSACTION_QUEUE_SIZE_SPI - _transaction_buffer.reset(); -#endif -} - -void SPI::abort_all_transfers() -{ - clear_transfer_buffer(); - abort_transfer(); -} - -int SPI::set_dma_usage(DMAUsage usage) -{ - if (spi_active(&_spi)) { - return -1; - } - _usage = usage; - return 0; -} - -int SPI::queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event) -{ -#if TRANSACTION_QUEUE_SIZE_SPI - transaction_t t; - - t.tx_buffer = const_cast<void *>(tx_buffer); - t.tx_length = tx_length; - t.rx_buffer = rx_buffer; - t.rx_length = rx_length; - t.event = event; - t.callback = callback; - t.width = bit_width; - Transaction<SPI> transaction(this, t); - if (_transaction_buffer.full()) { - return -1; // the buffer is full - } else { - _transaction_buffer.push(transaction); - return 0; - } -#else - return -1; -#endif -} - -void SPI::start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event) -{ - aquire(); - _callback = callback; - _irq.callback(&SPI::irq_handler_asynch); - spi_master_transfer(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, bit_width, _irq.entry(), event , _usage); -} - -#if TRANSACTION_QUEUE_SIZE_SPI - -void SPI::start_transaction(transaction_t *data) -{ - start_transfer(data->tx_buffer, data->tx_length, data->rx_buffer, data->rx_length, data->width, data->callback, data->event); -} - -void SPI::dequeue_transaction() -{ - Transaction<SPI> t; - if (_transaction_buffer.pop(t)) { - SPI* obj = t.get_object(); - transaction_t* data = t.get_transaction(); - obj->start_transaction(data); - } -} - -#endif - -void SPI::irq_handler_asynch(void) -{ - int event = spi_irq_handler_asynch(&_spi); - if (_callback && (event & SPI_EVENT_ALL)) { - _callback.call(event & SPI_EVENT_ALL); - } -#if TRANSACTION_QUEUE_SIZE_SPI - if (event & (SPI_EVENT_ALL | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)) { - // SPI peripheral is free (event happend), dequeue transaction - dequeue_transaction(); - } -#endif -} - -#endif - -} // namespace mbed - -#endif