CAN.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* mbed Microcontroller Library
  2. * Copyright (c) 2006-2013 ARM Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "drivers/CAN.h"
  17. #if DEVICE_CAN
  18. #include "cmsis.h"
  19. #include "platform/mbed_power_mgmt.h"
  20. namespace mbed {
  21. CAN::CAN(PinName rd, PinName td) : _can(), _irq()
  22. {
  23. // No lock needed in constructor
  24. for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
  25. _irq[i] = NULL;
  26. }
  27. can_init(&_can, rd, td);
  28. can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
  29. }
  30. CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq()
  31. {
  32. // No lock needed in constructor
  33. for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
  34. _irq[i] = NULL;
  35. }
  36. can_init_freq(&_can, rd, td, hz);
  37. can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
  38. }
  39. CAN::~CAN()
  40. {
  41. // No lock needed in destructor
  42. // Detaching interrupts releases the sleep lock if it was locked
  43. for (int irq = 0; irq < IrqCnt; irq++) {
  44. attach(NULL, (IrqType)irq);
  45. }
  46. can_irq_free(&_can);
  47. can_free(&_can);
  48. }
  49. int CAN::frequency(int f)
  50. {
  51. lock();
  52. int ret = can_frequency(&_can, f);
  53. unlock();
  54. return ret;
  55. }
  56. int CAN::write(CANMessage msg)
  57. {
  58. lock();
  59. int ret = can_write(&_can, msg, 0);
  60. unlock();
  61. return ret;
  62. }
  63. int CAN::read(CANMessage &msg, int handle)
  64. {
  65. lock();
  66. int ret = can_read(&_can, &msg, handle);
  67. unlock();
  68. return ret;
  69. }
  70. void CAN::reset()
  71. {
  72. lock();
  73. can_reset(&_can);
  74. unlock();
  75. }
  76. unsigned char CAN::rderror()
  77. {
  78. lock();
  79. int ret = can_rderror(&_can);
  80. unlock();
  81. return ret;
  82. }
  83. unsigned char CAN::tderror()
  84. {
  85. lock();
  86. int ret = can_tderror(&_can);
  87. unlock();
  88. return ret;
  89. }
  90. void CAN::monitor(bool silent)
  91. {
  92. lock();
  93. can_monitor(&_can, (silent) ? 1 : 0);
  94. unlock();
  95. }
  96. int CAN::mode(Mode mode)
  97. {
  98. lock();
  99. int ret = can_mode(&_can, (CanMode)mode);
  100. unlock();
  101. return ret;
  102. }
  103. int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle)
  104. {
  105. lock();
  106. int ret = can_filter(&_can, id, mask, format, handle);
  107. unlock();
  108. return ret;
  109. }
  110. void CAN::attach(Callback<void()> func, IrqType type)
  111. {
  112. lock();
  113. if (func) {
  114. // lock deep sleep only the first time
  115. if (!_irq[(CanIrqType)type]) {
  116. sleep_manager_lock_deep_sleep();
  117. }
  118. _irq[(CanIrqType)type] = func;
  119. can_irq_set(&_can, (CanIrqType)type, 1);
  120. } else {
  121. // unlock deep sleep only the first time
  122. if (_irq[(CanIrqType)type]) {
  123. sleep_manager_unlock_deep_sleep();
  124. }
  125. _irq[(CanIrqType)type] = NULL;
  126. can_irq_set(&_can, (CanIrqType)type, 0);
  127. }
  128. unlock();
  129. }
  130. void CAN::_irq_handler(uint32_t id, CanIrqType type)
  131. {
  132. CAN *handler = (CAN *)id;
  133. if (handler->_irq[type]) {
  134. handler->_irq[type].call();
  135. }
  136. }
  137. void CAN::lock()
  138. {
  139. _mutex.lock();
  140. }
  141. void CAN::unlock()
  142. {
  143. _mutex.unlock();
  144. }
  145. } // namespace mbed
  146. #endif