mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

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  * 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 
00029     for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
00030         _irq[i] = NULL;
00031     }
00032 
00033     can_init(&_can, rd, td);
00034     can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
00035 }
00036 
00037 CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq()
00038 {
00039     // No lock needed in constructor
00040 
00041     for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
00042         _irq[i] = NULL;
00043     }
00044 
00045     can_init_freq(&_can, rd, td, hz);
00046     can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
00047 }
00048 
00049 CAN::~CAN()
00050 {
00051     // No lock needed in destructor
00052 
00053     // Detaching interrupts releases the sleep lock if it was locked
00054     for (int irq = 0; irq < IrqCnt; irq++) {
00055         attach(NULL, (IrqType)irq);
00056     }
00057     can_irq_free(&_can);
00058     can_free(&_can);
00059 }
00060 
00061 int CAN::frequency(int f)
00062 {
00063     lock();
00064     int ret = can_frequency(&_can, f);
00065     unlock();
00066     return ret;
00067 }
00068 
00069 int CAN::write(CANMessage msg)
00070 {
00071     lock();
00072     int ret = can_write(&_can, msg, 0);
00073     unlock();
00074     return ret;
00075 }
00076 
00077 int CAN::read(CANMessage &msg, int handle)
00078 {
00079     lock();
00080     int ret = can_read(&_can, &msg, handle);
00081     unlock();
00082     return ret;
00083 }
00084 
00085 void CAN::reset()
00086 {
00087     lock();
00088     can_reset(&_can);
00089     unlock();
00090 }
00091 
00092 unsigned char CAN::rderror()
00093 {
00094     lock();
00095     int ret = can_rderror(&_can);
00096     unlock();
00097     return ret;
00098 }
00099 
00100 unsigned char CAN::tderror()
00101 {
00102     lock();
00103     int ret = can_tderror(&_can);
00104     unlock();
00105     return ret;
00106 }
00107 
00108 void CAN::monitor(bool silent)
00109 {
00110     lock();
00111     can_monitor(&_can, (silent) ? 1 : 0);
00112     unlock();
00113 }
00114 
00115 int CAN::mode(Mode mode)
00116 {
00117     lock();
00118     int ret = can_mode(&_can, (CanMode)mode);
00119     unlock();
00120     return ret;
00121 }
00122 
00123 int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle)
00124 {
00125     lock();
00126     int ret = can_filter(&_can, id, mask, format, handle);
00127     unlock();
00128     return ret;
00129 }
00130 
00131 void CAN::attach(Callback<void()> func, IrqType type)
00132 {
00133     lock();
00134     if (func) {
00135         // lock deep sleep only the first time
00136         if (!_irq[(CanIrqType)type]) {
00137             sleep_manager_lock_deep_sleep();
00138         }
00139         _irq[(CanIrqType)type] = func;
00140         can_irq_set(&_can, (CanIrqType)type, 1);
00141     } else {
00142         // unlock deep sleep only the first time
00143         if (_irq[(CanIrqType)type]) {
00144             sleep_manager_unlock_deep_sleep();
00145         }
00146         _irq[(CanIrqType)type] = NULL;
00147         can_irq_set(&_can, (CanIrqType)type, 0);
00148     }
00149     unlock();
00150 }
00151 
00152 void CAN::_irq_handler(uint32_t id, CanIrqType type)
00153 {
00154     CAN *handler = (CAN *)id;
00155     if (handler->_irq[type]) {
00156         handler->_irq[type].call();
00157     }
00158 }
00159 
00160 void CAN::lock()
00161 {
00162     _mutex.lock();
00163 }
00164 
00165 void CAN::unlock()
00166 {
00167     _mutex.unlock();
00168 }
00169 
00170 } // namespace mbed
00171 
00172 #endif