Rtos API example

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