Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CAN.cpp Source File

CAN.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2019 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #include "drivers/CAN.h"
00018 
00019 #if DEVICE_CAN
00020 
00021 #include "platform/mbed_power_mgmt.h"
00022 
00023 namespace mbed {
00024 
00025 CAN::CAN(PinName rd, PinName td) : _can(), _irq()
00026 {
00027     // No lock needed in constructor
00028     can_init(&_can, rd, td);
00029     can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
00030 }
00031 
00032 CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq()
00033 {
00034     // No lock needed in constructor
00035     can_init_freq(&_can, rd, td, hz);
00036     can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
00037 }
00038 
00039 CAN::CAN(const can_pinmap_t &pinmap) : _can(), _irq()
00040 {
00041     // No lock needed in constructor
00042     can_init_direct(&_can, &pinmap);
00043     can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
00044 }
00045 
00046 CAN::CAN(const can_pinmap_t &pinmap, int hz) : _can(), _irq()
00047 {
00048     // No lock needed in constructor
00049     can_init_freq_direct(&_can, &pinmap, hz);
00050     can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
00051 }
00052 
00053 CAN::~CAN()
00054 {
00055     // No lock needed in destructor
00056 
00057     // Detaching interrupts releases the sleep lock if it was locked
00058     for (int irq = 0; irq < IrqCnt; irq++) {
00059         attach(NULL, (IrqType)irq);
00060     }
00061     can_irq_free(&_can);
00062     can_free(&_can);
00063 }
00064 
00065 int CAN::frequency(int f)
00066 {
00067     lock();
00068     int ret = can_frequency(&_can, f);
00069     unlock();
00070     return ret;
00071 }
00072 
00073 int CAN::write(CANMessage msg)
00074 {
00075     lock();
00076     int ret = can_write(&_can, msg, 0);
00077     unlock();
00078     return ret;
00079 }
00080 
00081 int CAN::read(CANMessage &msg, int handle)
00082 {
00083     lock();
00084     int ret = can_read(&_can, &msg, handle);
00085     unlock();
00086     return ret;
00087 }
00088 
00089 void CAN::reset()
00090 {
00091     lock();
00092     can_reset(&_can);
00093     unlock();
00094 }
00095 
00096 unsigned char CAN::rderror()
00097 {
00098     lock();
00099     int ret = can_rderror(&_can);
00100     unlock();
00101     return ret;
00102 }
00103 
00104 unsigned char CAN::tderror()
00105 {
00106     lock();
00107     int ret = can_tderror(&_can);
00108     unlock();
00109     return ret;
00110 }
00111 
00112 void CAN::monitor(bool silent)
00113 {
00114     lock();
00115     can_monitor(&_can, (silent) ? 1 : 0);
00116     unlock();
00117 }
00118 
00119 int CAN::mode(Mode mode)
00120 {
00121     lock();
00122     int ret = can_mode(&_can, (CanMode)mode);
00123     unlock();
00124     return ret;
00125 }
00126 
00127 int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle)
00128 {
00129     lock();
00130     int ret = can_filter(&_can, id, mask, format, handle);
00131     unlock();
00132     return ret;
00133 }
00134 
00135 void CAN::attach(Callback<void()> func, IrqType type)
00136 {
00137     lock();
00138     if (func) {
00139         // lock deep sleep only the first time
00140         if (!_irq[(CanIrqType)type]) {
00141             sleep_manager_lock_deep_sleep();
00142         }
00143         _irq[(CanIrqType)type] = func;
00144         can_irq_set(&_can, (CanIrqType)type, 1);
00145     } else {
00146         // unlock deep sleep only the first time
00147         if (_irq[(CanIrqType)type]) {
00148             sleep_manager_unlock_deep_sleep();
00149         }
00150         _irq[(CanIrqType)type] = NULL;
00151         can_irq_set(&_can, (CanIrqType)type, 0);
00152     }
00153     unlock();
00154 }
00155 
00156 void CAN::_irq_handler(uint32_t id, CanIrqType type)
00157 {
00158     CAN *handler = (CAN *)id;
00159     if (handler->_irq[type]) {
00160         handler->_irq[type].call();
00161     }
00162 }
00163 
00164 void CAN::lock()
00165 {
00166     _mutex.lock();
00167 }
00168 
00169 void CAN::unlock()
00170 {
00171     _mutex.unlock();
00172 }
00173 
00174 } // namespace mbed
00175 
00176 #endif