123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "drivers/CAN.h"
- #if DEVICE_CAN
- #include "cmsis.h"
- #include "platform/mbed_power_mgmt.h"
- namespace mbed {
- CAN::CAN(PinName rd, PinName td) : _can(), _irq()
- {
- // No lock needed in constructor
- for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
- _irq[i] = NULL;
- }
- can_init(&_can, rd, td);
- can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
- }
- CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq()
- {
- // No lock needed in constructor
- for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
- _irq[i] = NULL;
- }
- can_init_freq(&_can, rd, td, hz);
- can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
- }
- CAN::~CAN()
- {
- // No lock needed in destructor
- // Detaching interrupts releases the sleep lock if it was locked
- for (int irq = 0; irq < IrqCnt; irq++) {
- attach(NULL, (IrqType)irq);
- }
- can_irq_free(&_can);
- can_free(&_can);
- }
- int CAN::frequency(int f)
- {
- lock();
- int ret = can_frequency(&_can, f);
- unlock();
- return ret;
- }
- int CAN::write(CANMessage msg)
- {
- lock();
- int ret = can_write(&_can, msg, 0);
- unlock();
- return ret;
- }
- int CAN::read(CANMessage &msg, int handle)
- {
- lock();
- int ret = can_read(&_can, &msg, handle);
- unlock();
- return ret;
- }
- void CAN::reset()
- {
- lock();
- can_reset(&_can);
- unlock();
- }
- unsigned char CAN::rderror()
- {
- lock();
- int ret = can_rderror(&_can);
- unlock();
- return ret;
- }
- unsigned char CAN::tderror()
- {
- lock();
- int ret = can_tderror(&_can);
- unlock();
- return ret;
- }
- void CAN::monitor(bool silent)
- {
- lock();
- can_monitor(&_can, (silent) ? 1 : 0);
- unlock();
- }
- int CAN::mode(Mode mode)
- {
- lock();
- int ret = can_mode(&_can, (CanMode)mode);
- unlock();
- return ret;
- }
- int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle)
- {
- lock();
- int ret = can_filter(&_can, id, mask, format, handle);
- unlock();
- return ret;
- }
- void CAN::attach(Callback<void()> func, IrqType type)
- {
- lock();
- if (func) {
- // lock deep sleep only the first time
- if (!_irq[(CanIrqType)type]) {
- sleep_manager_lock_deep_sleep();
- }
- _irq[(CanIrqType)type] = func;
- can_irq_set(&_can, (CanIrqType)type, 1);
- } else {
- // unlock deep sleep only the first time
- if (_irq[(CanIrqType)type]) {
- sleep_manager_unlock_deep_sleep();
- }
- _irq[(CanIrqType)type] = NULL;
- can_irq_set(&_can, (CanIrqType)type, 0);
- }
- unlock();
- }
- void CAN::_irq_handler(uint32_t id, CanIrqType type)
- {
- CAN *handler = (CAN *)id;
- if (handler->_irq[type]) {
- handler->_irq[type].call();
- }
- }
- void CAN::lock()
- {
- _mutex.lock();
- }
- void CAN::unlock()
- {
- _mutex.unlock();
- }
- } // namespace mbed
- #endif
|