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

Committer:
vipinranka
Date:
Wed Jan 11 11:41:30 2017 +0000
Revision:
12:9a20164dcc47
This is the final version MGAS Project for Renesas GR Peach Design Contest

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vipinranka 12:9a20164dcc47 1 /* mbed Microcontroller Library
vipinranka 12:9a20164dcc47 2 * Copyright (c) 2006-2013 ARM Limited
vipinranka 12:9a20164dcc47 3 *
vipinranka 12:9a20164dcc47 4 * Licensed under the Apache License, Version 2.0 (the "License");
vipinranka 12:9a20164dcc47 5 * you may not use this file except in compliance with the License.
vipinranka 12:9a20164dcc47 6 * You may obtain a copy of the License at
vipinranka 12:9a20164dcc47 7 *
vipinranka 12:9a20164dcc47 8 * http://www.apache.org/licenses/LICENSE-2.0
vipinranka 12:9a20164dcc47 9 *
vipinranka 12:9a20164dcc47 10 * Unless required by applicable law or agreed to in writing, software
vipinranka 12:9a20164dcc47 11 * distributed under the License is distributed on an "AS IS" BASIS,
vipinranka 12:9a20164dcc47 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vipinranka 12:9a20164dcc47 13 * See the License for the specific language governing permissions and
vipinranka 12:9a20164dcc47 14 * limitations under the License.
vipinranka 12:9a20164dcc47 15 */
vipinranka 12:9a20164dcc47 16 #include "drivers/SPI.h"
vipinranka 12:9a20164dcc47 17 #include "platform/critical.h"
vipinranka 12:9a20164dcc47 18
vipinranka 12:9a20164dcc47 19 #if DEVICE_SPI
vipinranka 12:9a20164dcc47 20
vipinranka 12:9a20164dcc47 21 namespace mbed {
vipinranka 12:9a20164dcc47 22
vipinranka 12:9a20164dcc47 23 #if DEVICE_SPI_ASYNCH && TRANSACTION_QUEUE_SIZE_SPI
vipinranka 12:9a20164dcc47 24 CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> SPI::_transaction_buffer;
vipinranka 12:9a20164dcc47 25 #endif
vipinranka 12:9a20164dcc47 26
vipinranka 12:9a20164dcc47 27 SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
vipinranka 12:9a20164dcc47 28 _spi(),
vipinranka 12:9a20164dcc47 29 #if DEVICE_SPI_ASYNCH
vipinranka 12:9a20164dcc47 30 _irq(this),
vipinranka 12:9a20164dcc47 31 _usage(DMA_USAGE_NEVER),
vipinranka 12:9a20164dcc47 32 #endif
vipinranka 12:9a20164dcc47 33 _bits(8),
vipinranka 12:9a20164dcc47 34 _mode(0),
vipinranka 12:9a20164dcc47 35 _hz(1000000) {
vipinranka 12:9a20164dcc47 36 // No lock needed in the constructor
vipinranka 12:9a20164dcc47 37
vipinranka 12:9a20164dcc47 38 spi_init(&_spi, mosi, miso, sclk, ssel);
vipinranka 12:9a20164dcc47 39 aquire();
vipinranka 12:9a20164dcc47 40 }
vipinranka 12:9a20164dcc47 41
vipinranka 12:9a20164dcc47 42 void SPI::format(int bits, int mode) {
vipinranka 12:9a20164dcc47 43 lock();
vipinranka 12:9a20164dcc47 44 _bits = bits;
vipinranka 12:9a20164dcc47 45 _mode = mode;
vipinranka 12:9a20164dcc47 46 SPI::_owner = NULL; // Not that elegant, but works. rmeyer
vipinranka 12:9a20164dcc47 47 aquire();
vipinranka 12:9a20164dcc47 48 unlock();
vipinranka 12:9a20164dcc47 49 }
vipinranka 12:9a20164dcc47 50
vipinranka 12:9a20164dcc47 51 void SPI::frequency(int hz) {
vipinranka 12:9a20164dcc47 52 lock();
vipinranka 12:9a20164dcc47 53 _hz = hz;
vipinranka 12:9a20164dcc47 54 SPI::_owner = NULL; // Not that elegant, but works. rmeyer
vipinranka 12:9a20164dcc47 55 aquire();
vipinranka 12:9a20164dcc47 56 unlock();
vipinranka 12:9a20164dcc47 57 }
vipinranka 12:9a20164dcc47 58
vipinranka 12:9a20164dcc47 59 SPI* SPI::_owner = NULL;
vipinranka 12:9a20164dcc47 60 SingletonPtr<PlatformMutex> SPI::_mutex;
vipinranka 12:9a20164dcc47 61
vipinranka 12:9a20164dcc47 62 // ignore the fact there are multiple physical spis, and always update if it wasnt us last
vipinranka 12:9a20164dcc47 63 void SPI::aquire() {
vipinranka 12:9a20164dcc47 64 lock();
vipinranka 12:9a20164dcc47 65 if (_owner != this) {
vipinranka 12:9a20164dcc47 66 spi_format(&_spi, _bits, _mode, 0);
vipinranka 12:9a20164dcc47 67 spi_frequency(&_spi, _hz);
vipinranka 12:9a20164dcc47 68 _owner = this;
vipinranka 12:9a20164dcc47 69 }
vipinranka 12:9a20164dcc47 70 unlock();
vipinranka 12:9a20164dcc47 71 }
vipinranka 12:9a20164dcc47 72
vipinranka 12:9a20164dcc47 73 int SPI::write(int value) {
vipinranka 12:9a20164dcc47 74 lock();
vipinranka 12:9a20164dcc47 75 aquire();
vipinranka 12:9a20164dcc47 76 int ret = spi_master_write(&_spi, value);
vipinranka 12:9a20164dcc47 77 unlock();
vipinranka 12:9a20164dcc47 78 return ret;
vipinranka 12:9a20164dcc47 79 }
vipinranka 12:9a20164dcc47 80
vipinranka 12:9a20164dcc47 81 void SPI::lock() {
vipinranka 12:9a20164dcc47 82 _mutex->lock();
vipinranka 12:9a20164dcc47 83 }
vipinranka 12:9a20164dcc47 84
vipinranka 12:9a20164dcc47 85 void SPI::unlock() {
vipinranka 12:9a20164dcc47 86 _mutex->unlock();
vipinranka 12:9a20164dcc47 87 }
vipinranka 12:9a20164dcc47 88
vipinranka 12:9a20164dcc47 89 #if DEVICE_SPI_ASYNCH
vipinranka 12:9a20164dcc47 90
vipinranka 12:9a20164dcc47 91 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)
vipinranka 12:9a20164dcc47 92 {
vipinranka 12:9a20164dcc47 93 if (spi_active(&_spi)) {
vipinranka 12:9a20164dcc47 94 return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event);
vipinranka 12:9a20164dcc47 95 }
vipinranka 12:9a20164dcc47 96 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event);
vipinranka 12:9a20164dcc47 97 return 0;
vipinranka 12:9a20164dcc47 98 }
vipinranka 12:9a20164dcc47 99
vipinranka 12:9a20164dcc47 100 void SPI::abort_transfer()
vipinranka 12:9a20164dcc47 101 {
vipinranka 12:9a20164dcc47 102 spi_abort_asynch(&_spi);
vipinranka 12:9a20164dcc47 103 #if TRANSACTION_QUEUE_SIZE_SPI
vipinranka 12:9a20164dcc47 104 dequeue_transaction();
vipinranka 12:9a20164dcc47 105 #endif
vipinranka 12:9a20164dcc47 106 }
vipinranka 12:9a20164dcc47 107
vipinranka 12:9a20164dcc47 108
vipinranka 12:9a20164dcc47 109 void SPI::clear_transfer_buffer()
vipinranka 12:9a20164dcc47 110 {
vipinranka 12:9a20164dcc47 111 #if TRANSACTION_QUEUE_SIZE_SPI
vipinranka 12:9a20164dcc47 112 _transaction_buffer.reset();
vipinranka 12:9a20164dcc47 113 #endif
vipinranka 12:9a20164dcc47 114 }
vipinranka 12:9a20164dcc47 115
vipinranka 12:9a20164dcc47 116 void SPI::abort_all_transfers()
vipinranka 12:9a20164dcc47 117 {
vipinranka 12:9a20164dcc47 118 clear_transfer_buffer();
vipinranka 12:9a20164dcc47 119 abort_transfer();
vipinranka 12:9a20164dcc47 120 }
vipinranka 12:9a20164dcc47 121
vipinranka 12:9a20164dcc47 122 int SPI::set_dma_usage(DMAUsage usage)
vipinranka 12:9a20164dcc47 123 {
vipinranka 12:9a20164dcc47 124 if (spi_active(&_spi)) {
vipinranka 12:9a20164dcc47 125 return -1;
vipinranka 12:9a20164dcc47 126 }
vipinranka 12:9a20164dcc47 127 _usage = usage;
vipinranka 12:9a20164dcc47 128 return 0;
vipinranka 12:9a20164dcc47 129 }
vipinranka 12:9a20164dcc47 130
vipinranka 12:9a20164dcc47 131 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)
vipinranka 12:9a20164dcc47 132 {
vipinranka 12:9a20164dcc47 133 #if TRANSACTION_QUEUE_SIZE_SPI
vipinranka 12:9a20164dcc47 134 transaction_t t;
vipinranka 12:9a20164dcc47 135
vipinranka 12:9a20164dcc47 136 t.tx_buffer = const_cast<void *>(tx_buffer);
vipinranka 12:9a20164dcc47 137 t.tx_length = tx_length;
vipinranka 12:9a20164dcc47 138 t.rx_buffer = rx_buffer;
vipinranka 12:9a20164dcc47 139 t.rx_length = rx_length;
vipinranka 12:9a20164dcc47 140 t.event = event;
vipinranka 12:9a20164dcc47 141 t.callback = callback;
vipinranka 12:9a20164dcc47 142 t.width = bit_width;
vipinranka 12:9a20164dcc47 143 Transaction<SPI> transaction(this, t);
vipinranka 12:9a20164dcc47 144 if (_transaction_buffer.full()) {
vipinranka 12:9a20164dcc47 145 return -1; // the buffer is full
vipinranka 12:9a20164dcc47 146 } else {
vipinranka 12:9a20164dcc47 147 core_util_critical_section_enter();
vipinranka 12:9a20164dcc47 148 _transaction_buffer.push(transaction);
vipinranka 12:9a20164dcc47 149 if (!spi_active(&_spi)) {
vipinranka 12:9a20164dcc47 150 dequeue_transaction();
vipinranka 12:9a20164dcc47 151 }
vipinranka 12:9a20164dcc47 152 core_util_critical_section_exit();
vipinranka 12:9a20164dcc47 153 return 0;
vipinranka 12:9a20164dcc47 154 }
vipinranka 12:9a20164dcc47 155 #else
vipinranka 12:9a20164dcc47 156 return -1;
vipinranka 12:9a20164dcc47 157 #endif
vipinranka 12:9a20164dcc47 158 }
vipinranka 12:9a20164dcc47 159
vipinranka 12:9a20164dcc47 160 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)
vipinranka 12:9a20164dcc47 161 {
vipinranka 12:9a20164dcc47 162 aquire();
vipinranka 12:9a20164dcc47 163 _callback = callback;
vipinranka 12:9a20164dcc47 164 _irq.callback(&SPI::irq_handler_asynch);
vipinranka 12:9a20164dcc47 165 spi_master_transfer(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, bit_width, _irq.entry(), event , _usage);
vipinranka 12:9a20164dcc47 166 }
vipinranka 12:9a20164dcc47 167
vipinranka 12:9a20164dcc47 168 #if TRANSACTION_QUEUE_SIZE_SPI
vipinranka 12:9a20164dcc47 169
vipinranka 12:9a20164dcc47 170 void SPI::start_transaction(transaction_t *data)
vipinranka 12:9a20164dcc47 171 {
vipinranka 12:9a20164dcc47 172 start_transfer(data->tx_buffer, data->tx_length, data->rx_buffer, data->rx_length, data->width, data->callback, data->event);
vipinranka 12:9a20164dcc47 173 }
vipinranka 12:9a20164dcc47 174
vipinranka 12:9a20164dcc47 175 void SPI::dequeue_transaction()
vipinranka 12:9a20164dcc47 176 {
vipinranka 12:9a20164dcc47 177 Transaction<SPI> t;
vipinranka 12:9a20164dcc47 178 if (_transaction_buffer.pop(t)) {
vipinranka 12:9a20164dcc47 179 SPI* obj = t.get_object();
vipinranka 12:9a20164dcc47 180 transaction_t* data = t.get_transaction();
vipinranka 12:9a20164dcc47 181 obj->start_transaction(data);
vipinranka 12:9a20164dcc47 182 }
vipinranka 12:9a20164dcc47 183 }
vipinranka 12:9a20164dcc47 184
vipinranka 12:9a20164dcc47 185 #endif
vipinranka 12:9a20164dcc47 186
vipinranka 12:9a20164dcc47 187 void SPI::irq_handler_asynch(void)
vipinranka 12:9a20164dcc47 188 {
vipinranka 12:9a20164dcc47 189 int event = spi_irq_handler_asynch(&_spi);
vipinranka 12:9a20164dcc47 190 if (_callback && (event & SPI_EVENT_ALL)) {
vipinranka 12:9a20164dcc47 191 _callback.call(event & SPI_EVENT_ALL);
vipinranka 12:9a20164dcc47 192 }
vipinranka 12:9a20164dcc47 193 #if TRANSACTION_QUEUE_SIZE_SPI
vipinranka 12:9a20164dcc47 194 if (event & (SPI_EVENT_ALL | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)) {
vipinranka 12:9a20164dcc47 195 // SPI peripheral is free (event happend), dequeue transaction
vipinranka 12:9a20164dcc47 196 dequeue_transaction();
vipinranka 12:9a20164dcc47 197 }
vipinranka 12:9a20164dcc47 198 #endif
vipinranka 12:9a20164dcc47 199 }
vipinranka 12:9a20164dcc47 200
vipinranka 12:9a20164dcc47 201 #endif
vipinranka 12:9a20164dcc47 202
vipinranka 12:9a20164dcc47 203 } // namespace mbed
vipinranka 12:9a20164dcc47 204
vipinranka 12:9a20164dcc47 205 #endif