takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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