CanIface.cpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262
  1. /*
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2014 Pavel Kirienko
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. * this software and associated documentation files (the "Software"), to deal in
  8. * the Software without restriction, including without limitation the rights to
  9. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. * the Software, and to permit persons to whom the Software is furnished to do so,
  11. * subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. /*
  24. * This file is free software: you can redistribute it and/or modify it
  25. * under the terms of the GNU General Public License as published by the
  26. * Free Software Foundation, either version 3 of the License, or
  27. * (at your option) any later version.
  28. *
  29. * This file is distributed in the hope that it will be useful, but
  30. * WITHOUT ANY WARRANTY; without even the implied warranty of
  31. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  32. * See the GNU General Public License for more details.
  33. *
  34. * You should have received a copy of the GNU General Public License along
  35. * with this program. If not, see <http://www.gnu.org/licenses/>.
  36. *
  37. * Code by Siddharth Bharat Purohit
  38. */
  39. #include "AP_HAL_ChibiOS.h"
  40. #if HAL_WITH_UAVCAN
  41. #include <cassert>
  42. #include <cstring>
  43. #include "CANClock.h"
  44. #include "CANInternal.h"
  45. #include "CANSerialRouter.h"
  46. #include <AP_UAVCAN/AP_UAVCAN_SLCAN.h>
  47. # include <hal.h>
  48. # if !defined(STM32H7XX)
  49. #include "CANIface.h"
  50. #if CH_KERNEL_MAJOR == 2
  51. # if !(defined(STM32F10X_CL) || defined(STM32F2XX) || defined(STM32F3XX) || defined(STM32F4XX))
  52. // IRQ numbers
  53. # define CAN1_RX0_IRQn USB_LP_CAN1_RX0_IRQn
  54. # define CAN1_TX_IRQn USB_HP_CAN1_TX_IRQn
  55. // IRQ vectors
  56. # if !defined(CAN1_RX0_IRQHandler) || !defined(CAN1_TX_IRQHandler)
  57. # define CAN1_TX_IRQHandler USB_HP_CAN1_TX_IRQHandler
  58. # define CAN1_RX0_IRQHandler USB_LP_CAN1_RX0_IRQHandler
  59. # endif
  60. # endif
  61. #endif
  62. #if (CH_KERNEL_MAJOR == 3 || CH_KERNEL_MAJOR == 4 || CH_KERNEL_MAJOR == 5 || CH_KERNEL_MAJOR == 6)
  63. #define CAN1_TX_IRQHandler STM32_CAN1_TX_HANDLER
  64. #define CAN1_RX0_IRQHandler STM32_CAN1_RX0_HANDLER
  65. #define CAN1_RX1_IRQHandler STM32_CAN1_RX1_HANDLER
  66. #define CAN2_TX_IRQHandler STM32_CAN2_TX_HANDLER
  67. #define CAN2_RX0_IRQHandler STM32_CAN2_RX0_HANDLER
  68. #define CAN2_RX1_IRQHandler STM32_CAN2_RX1_HANDLER
  69. #endif
  70. /* STM32F3's only CAN inteface does not have a number. */
  71. #if defined(STM32F3XX)
  72. #define RCC_APB1ENR_CAN1EN RCC_APB1ENR_CANEN
  73. #define RCC_APB1RSTR_CAN1RST RCC_APB1RSTR_CANRST
  74. #define CAN1_TX_IRQn CAN_TX_IRQn
  75. #define CAN1_RX0_IRQn CAN_RX0_IRQn
  76. #define CAN1_RX1_IRQn CAN_RX1_IRQn
  77. #define CAN1_TX_IRQHandler CAN_TX_IRQHandler
  78. #define CAN1_RX0_IRQHandler CAN_RX0_IRQHandler
  79. #define CAN1_RX1_IRQHandler CAN_RX1_IRQHandler
  80. #endif
  81. namespace ChibiOS_CAN
  82. {
  83. namespace
  84. {
  85. CanIface* ifaces[UAVCAN_STM32_NUM_IFACES] =
  86. {
  87. UAVCAN_NULLPTR
  88. #if UAVCAN_STM32_NUM_IFACES > 1
  89. , UAVCAN_NULLPTR
  90. #endif
  91. };
  92. inline void handleTxInterrupt(uavcan::uint8_t iface_index)
  93. {
  94. UAVCAN_ASSERT(iface_index < UAVCAN_STM32_NUM_IFACES);
  95. uavcan::uint64_t utc_usec = clock::getUtcUSecFromCanInterrupt();
  96. if (utc_usec > 0)
  97. {
  98. utc_usec--;
  99. }
  100. if (ifaces[iface_index] != UAVCAN_NULLPTR)
  101. {
  102. ifaces[iface_index]->handleTxInterrupt(utc_usec);
  103. }
  104. else
  105. {
  106. UAVCAN_ASSERT(0);
  107. }
  108. }
  109. inline void handleRxInterrupt(uavcan::uint8_t iface_index, uavcan::uint8_t fifo_index)
  110. {
  111. UAVCAN_ASSERT(iface_index < UAVCAN_STM32_NUM_IFACES);
  112. uavcan::uint64_t utc_usec = clock::getUtcUSecFromCanInterrupt();
  113. if (utc_usec > 0)
  114. {
  115. utc_usec--;
  116. }
  117. if (ifaces[iface_index] != UAVCAN_NULLPTR)
  118. {
  119. ifaces[iface_index]->handleRxInterrupt(fifo_index, utc_usec);
  120. }
  121. else
  122. {
  123. UAVCAN_ASSERT(0);
  124. }
  125. }
  126. } // namespace
  127. #if AP_UAVCAN_SLCAN_ENABLED
  128. SLCANRouter CanIface::_slcan_router;
  129. #endif
  130. /*
  131. * CanIface::RxQueue
  132. */
  133. void CanIface::RxQueue::registerOverflow()
  134. {
  135. if (overflow_cnt_ < 0xFFFFFFFF)
  136. {
  137. overflow_cnt_++;
  138. }
  139. }
  140. void CanIface::RxQueue::push(const uavcan::CanFrame& frame, const uint64_t& utc_usec, uavcan::CanIOFlags flags)
  141. {
  142. buf_[in_].frame = frame;
  143. buf_[in_].utc_usec = utc_usec;
  144. buf_[in_].flags = flags;
  145. in_++;
  146. if (in_ >= capacity_)
  147. {
  148. in_ = 0;
  149. }
  150. len_++;
  151. if (len_ > capacity_)
  152. {
  153. len_ = capacity_;
  154. registerOverflow();
  155. out_++;
  156. if (out_ >= capacity_)
  157. {
  158. out_ = 0;
  159. }
  160. }
  161. }
  162. void CanIface::RxQueue::pop(uavcan::CanFrame& out_frame, uavcan::uint64_t& out_utc_usec, uavcan::CanIOFlags& out_flags)
  163. {
  164. if (len_ > 0)
  165. {
  166. out_frame = buf_[out_].frame;
  167. out_utc_usec = buf_[out_].utc_usec;
  168. out_flags = buf_[out_].flags;
  169. out_++;
  170. if (out_ >= capacity_)
  171. {
  172. out_ = 0;
  173. }
  174. len_--;
  175. }
  176. else { UAVCAN_ASSERT(0); }
  177. }
  178. void CanIface::RxQueue::reset()
  179. {
  180. in_ = 0;
  181. out_ = 0;
  182. len_ = 0;
  183. overflow_cnt_ = 0;
  184. }
  185. /*
  186. * CanIface
  187. */
  188. const uavcan::uint32_t CanIface::TSR_ABRQx[CanIface::NumTxMailboxes] =
  189. {
  190. bxcan::TSR_ABRQ0,
  191. bxcan::TSR_ABRQ1,
  192. bxcan::TSR_ABRQ2
  193. };
  194. int CanIface::computeTimings(const uavcan::uint32_t target_bitrate, Timings& out_timings)
  195. {
  196. if (target_bitrate < 1)
  197. {
  198. return -ErrInvalidBitRate;
  199. }
  200. /*
  201. * Hardware configuration
  202. */
  203. const uavcan::uint32_t pclk = STM32_PCLK1;
  204. static const int MaxBS1 = 16;
  205. static const int MaxBS2 = 8;
  206. /*
  207. * Ref. "Automatic Baudrate Detection in CANopen Networks", U. Koppe, MicroControl GmbH & Co. KG
  208. * CAN in Automation, 2003
  209. *
  210. * According to the source, optimal quanta per bit are:
  211. * Bitrate Optimal Maximum
  212. * 1000 kbps 8 10
  213. * 500 kbps 16 17
  214. * 250 kbps 16 17
  215. * 125 kbps 16 17
  216. */
  217. const int max_quanta_per_bit = (target_bitrate >= 1000000) ? 10 : 17;
  218. UAVCAN_ASSERT(max_quanta_per_bit <= (MaxBS1 + MaxBS2));
  219. static const int MaxSamplePointLocation = 900;
  220. /*
  221. * Computing (prescaler * BS):
  222. * BITRATE = 1 / (PRESCALER * (1 / PCLK) * (1 + BS1 + BS2)) -- See the Reference Manual
  223. * BITRATE = PCLK / (PRESCALER * (1 + BS1 + BS2)) -- Simplified
  224. * let:
  225. * BS = 1 + BS1 + BS2 -- Number of time quanta per bit
  226. * PRESCALER_BS = PRESCALER * BS
  227. * ==>
  228. * PRESCALER_BS = PCLK / BITRATE
  229. */
  230. const uavcan::uint32_t prescaler_bs = pclk / target_bitrate;
  231. /*
  232. * Searching for such prescaler value so that the number of quanta per bit is highest.
  233. */
  234. uavcan::uint8_t bs1_bs2_sum = uavcan::uint8_t(max_quanta_per_bit - 1);
  235. while ((prescaler_bs % (1 + bs1_bs2_sum)) != 0)
  236. {
  237. if (bs1_bs2_sum <= 2)
  238. {
  239. return -ErrInvalidBitRate; // No solution
  240. }
  241. bs1_bs2_sum--;
  242. }
  243. const uavcan::uint32_t prescaler = prescaler_bs / (1 + bs1_bs2_sum);
  244. if ((prescaler < 1U) || (prescaler > 1024U))
  245. {
  246. return -ErrInvalidBitRate; // No solution
  247. }
  248. /*
  249. * Now we have a constraint: (BS1 + BS2) == bs1_bs2_sum.
  250. * We need to find the values so that the sample point is as close as possible to the optimal value.
  251. *
  252. * Solve[(1 + bs1)/(1 + bs1 + bs2) == 7/8, bs2] (* Where 7/8 is 0.875, the recommended sample point location *)
  253. * {{bs2 -> (1 + bs1)/7}}
  254. *
  255. * Hence:
  256. * bs2 = (1 + bs1) / 7
  257. * bs1 = (7 * bs1_bs2_sum - 1) / 8
  258. *
  259. * Sample point location can be computed as follows:
  260. * Sample point location = (1 + bs1) / (1 + bs1 + bs2)
  261. *
  262. * Since the optimal solution is so close to the maximum, we prepare two solutions, and then pick the best one:
  263. * - With rounding to nearest
  264. * - With rounding to zero
  265. */
  266. struct BsPair
  267. {
  268. uavcan::uint8_t bs1;
  269. uavcan::uint8_t bs2;
  270. uavcan::uint16_t sample_point_permill;
  271. BsPair() :
  272. bs1(0),
  273. bs2(0),
  274. sample_point_permill(0)
  275. { }
  276. BsPair(uavcan::uint8_t bs1_bs2_sum, uavcan::uint8_t arg_bs1) :
  277. bs1(arg_bs1),
  278. bs2(uavcan::uint8_t(bs1_bs2_sum - bs1)),
  279. sample_point_permill(uavcan::uint16_t(1000 * (1 + bs1) / (1 + bs1 + bs2)))
  280. {
  281. UAVCAN_ASSERT(bs1_bs2_sum > arg_bs1);
  282. }
  283. bool isValid() const { return (bs1 >= 1) && (bs1 <= MaxBS1) && (bs2 >= 1) && (bs2 <= MaxBS2); }
  284. };
  285. // First attempt with rounding to nearest
  286. BsPair solution(bs1_bs2_sum, uavcan::uint8_t(((7 * bs1_bs2_sum - 1) + 4) / 8));
  287. if (solution.sample_point_permill > MaxSamplePointLocation)
  288. {
  289. // Second attempt with rounding to zero
  290. solution = BsPair(bs1_bs2_sum, uavcan::uint8_t((7 * bs1_bs2_sum - 1) / 8));
  291. }
  292. /*
  293. * Final validation
  294. * Helpful Python:
  295. * def sample_point_from_btr(x):
  296. * assert 0b0011110010000000111111000000000 & x == 0
  297. * ts2,ts1,brp = (x>>20)&7, (x>>16)&15, x&511
  298. * return (1+ts1+1)/(1+ts1+1+ts2+1)
  299. *
  300. */
  301. if ((target_bitrate != (pclk / (prescaler * (1 + solution.bs1 + solution.bs2)))) || !solution.isValid())
  302. {
  303. UAVCAN_ASSERT(0);
  304. return -ErrLogic;
  305. }
  306. UAVCAN_STM32_LOG("Timings: quanta/bit: %d, sample point location: %.1f%%",
  307. int(1 + solution.bs1 + solution.bs2), float(solution.sample_point_permill) / 10.F);
  308. out_timings.prescaler = uavcan::uint16_t(prescaler - 1U);
  309. out_timings.sjw = 0; // Which means one
  310. out_timings.bs1 = uavcan::uint8_t(solution.bs1 - 1);
  311. out_timings.bs2 = uavcan::uint8_t(solution.bs2 - 1);
  312. return 0;
  313. }
  314. uavcan::int16_t CanIface::send(const uavcan::CanFrame& frame, uavcan::MonotonicTime tx_deadline,
  315. uavcan::CanIOFlags flags)
  316. {
  317. if (frame.isErrorFrame() || frame.dlc > 8)
  318. {
  319. return -ErrUnsupportedFrame;
  320. }
  321. /*
  322. * Normally we should perform the same check as in @ref canAcceptNewTxFrame(), because
  323. * it is possible that the highest-priority frame between select() and send() could have been
  324. * replaced with a lower priority one due to TX timeout. But we don't do this check because:
  325. *
  326. * - It is a highly unlikely scenario.
  327. *
  328. * - Frames do not timeout on a properly functioning bus. Since frames do not timeout, the new
  329. * frame can only have higher priority, which doesn't break the logic.
  330. *
  331. * - If high-priority frames are timing out in the TX queue, there's probably a lot of other
  332. * issues to take care of before this one becomes relevant.
  333. *
  334. * - It takes CPU time. Not just CPU time, but critical section time, which is expensive.
  335. */
  336. CriticalSectionLocker lock;
  337. /*
  338. * Seeking for an empty slot
  339. */
  340. uavcan::uint8_t txmailbox = 0xFF;
  341. if ((can_->TSR & bxcan::TSR_TME0) == bxcan::TSR_TME0)
  342. {
  343. txmailbox = 0;
  344. }
  345. else if ((can_->TSR & bxcan::TSR_TME1) == bxcan::TSR_TME1)
  346. {
  347. txmailbox = 1;
  348. }
  349. else if ((can_->TSR & bxcan::TSR_TME2) == bxcan::TSR_TME2)
  350. {
  351. txmailbox = 2;
  352. }
  353. else
  354. {
  355. return 0; // No transmission for you.
  356. }
  357. peak_tx_mailbox_index_ = uavcan::max(peak_tx_mailbox_index_, txmailbox); // Statistics
  358. /*
  359. * Setting up the mailbox
  360. */
  361. bxcan::TxMailboxType& mb = can_->TxMailbox[txmailbox];
  362. if (frame.isExtended())
  363. {
  364. mb.TIR = ((frame.id & uavcan::CanFrame::MaskExtID) << 3) | bxcan::TIR_IDE;
  365. }
  366. else
  367. {
  368. mb.TIR = ((frame.id & uavcan::CanFrame::MaskStdID) << 21);
  369. }
  370. if (frame.isRemoteTransmissionRequest())
  371. {
  372. mb.TIR |= bxcan::TIR_RTR;
  373. }
  374. mb.TDTR = frame.dlc;
  375. mb.TDHR = (uavcan::uint32_t(frame.data[7]) << 24) |
  376. (uavcan::uint32_t(frame.data[6]) << 16) |
  377. (uavcan::uint32_t(frame.data[5]) << 8) |
  378. (uavcan::uint32_t(frame.data[4]) << 0);
  379. mb.TDLR = (uavcan::uint32_t(frame.data[3]) << 24) |
  380. (uavcan::uint32_t(frame.data[2]) << 16) |
  381. (uavcan::uint32_t(frame.data[1]) << 8) |
  382. (uavcan::uint32_t(frame.data[0]) << 0);
  383. mb.TIR |= bxcan::TIR_TXRQ; // Go.
  384. /*
  385. * Registering the pending transmission so we can track its deadline and loopback it as needed
  386. */
  387. TxItem& txi = pending_tx_[txmailbox];
  388. txi.deadline = tx_deadline;
  389. txi.frame = frame;
  390. txi.loopback = (flags & uavcan::CanIOFlagLoopback) != 0;
  391. txi.abort_on_error = (flags & uavcan::CanIOFlagAbortOnError) != 0;
  392. txi.pending = true;
  393. return 1;
  394. }
  395. uavcan::int16_t CanIface::receive(uavcan::CanFrame& out_frame, uavcan::MonotonicTime& out_ts_monotonic,
  396. uavcan::UtcTime& out_ts_utc, uavcan::CanIOFlags& out_flags)
  397. {
  398. out_ts_monotonic = clock::getMonotonic(); // High precision is not required for monotonic timestamps
  399. uavcan::uint64_t utc_usec = 0;
  400. {
  401. CriticalSectionLocker lock;
  402. if (rx_queue_.getLength() == 0)
  403. {
  404. return 0;
  405. }
  406. rx_queue_.pop(out_frame, utc_usec, out_flags);
  407. }
  408. out_ts_utc = uavcan::UtcTime::fromUSec(utc_usec);
  409. return 1;
  410. }
  411. uavcan::int16_t CanIface::configureFilters(const uavcan::CanFilterConfig* filter_configs,
  412. uavcan::uint16_t num_configs)
  413. {
  414. if (num_configs <= NumFilters)
  415. {
  416. CriticalSectionLocker lock;
  417. can_->FMR |= bxcan::FMR_FINIT;
  418. // Slave (CAN2) gets half of the filters
  419. can_->FMR &= ~0x00003F00UL;
  420. can_->FMR |= static_cast<uint32_t>(NumFilters) << 8;
  421. can_->FFA1R = 0x0AAAAAAA; // FIFO's are interleaved between filters
  422. can_->FM1R = 0; // Identifier Mask mode
  423. can_->FS1R = 0x7ffffff; // Single 32-bit for all
  424. const uint8_t filter_start_index = (self_index_ == 0) ? 0 : NumFilters;
  425. if (num_configs == 0)
  426. {
  427. can_->FilterRegister[filter_start_index].FR1 = 0;
  428. can_->FilterRegister[filter_start_index].FR2 = 0;
  429. can_->FA1R = 1 << filter_start_index;
  430. }
  431. else
  432. {
  433. for (uint8_t i = 0; i < NumFilters; i++)
  434. {
  435. if (i < num_configs)
  436. {
  437. uint32_t id = 0;
  438. uint32_t mask = 0;
  439. const uavcan::CanFilterConfig* const cfg = filter_configs + i;
  440. if ((cfg->id & uavcan::CanFrame::FlagEFF) || !(cfg->mask & uavcan::CanFrame::FlagEFF))
  441. {
  442. id = (cfg->id & uavcan::CanFrame::MaskExtID) << 3;
  443. mask = (cfg->mask & uavcan::CanFrame::MaskExtID) << 3;
  444. id |= bxcan::RIR_IDE;
  445. }
  446. else
  447. {
  448. id = (cfg->id & uavcan::CanFrame::MaskStdID) << 21; // Regular std frames, nothing fancy.
  449. mask = (cfg->mask & uavcan::CanFrame::MaskStdID) << 21; // Boring.
  450. }
  451. if (cfg->id & uavcan::CanFrame::FlagRTR)
  452. {
  453. id |= bxcan::RIR_RTR;
  454. }
  455. if (cfg->mask & uavcan::CanFrame::FlagEFF)
  456. {
  457. mask |= bxcan::RIR_IDE;
  458. }
  459. if (cfg->mask & uavcan::CanFrame::FlagRTR)
  460. {
  461. mask |= bxcan::RIR_RTR;
  462. }
  463. can_->FilterRegister[filter_start_index + i].FR1 = id;
  464. can_->FilterRegister[filter_start_index + i].FR2 = mask;
  465. can_->FA1R |= (1 << (filter_start_index + i));
  466. }
  467. else
  468. {
  469. can_->FA1R &= ~(1 << (filter_start_index + i));
  470. }
  471. }
  472. }
  473. can_->FMR &= ~bxcan::FMR_FINIT;
  474. return 0;
  475. }
  476. return -ErrFilterNumConfigs;
  477. }
  478. bool CanIface::waitMsrINakBitStateChange(bool target_state)
  479. {
  480. const unsigned Timeout = 1000;
  481. for (unsigned wait_ack = 0; wait_ack < Timeout; wait_ack++)
  482. {
  483. const bool state = (can_->MSR & bxcan::MSR_INAK) != 0;
  484. if (state == target_state)
  485. {
  486. return true;
  487. }
  488. #if CH_KERNEL_MAJOR >= 5
  489. ::chThdSleep(chTimeMS2I(1));
  490. #else
  491. ::chThdSleep(MS2ST(1));
  492. #endif
  493. }
  494. return false;
  495. }
  496. int CanIface::init(const uavcan::uint32_t bitrate, const OperatingMode mode)
  497. {
  498. /*
  499. * We need to silence the controller in the first order, otherwise it may interfere with the following operations.
  500. */
  501. {
  502. CriticalSectionLocker lock;
  503. can_->MCR &= ~bxcan::MCR_SLEEP; // Exit sleep mode
  504. can_->MCR |= bxcan::MCR_INRQ; // Request init
  505. can_->IER = 0; // Disable interrupts while initialization is in progress
  506. }
  507. if (!waitMsrINakBitStateChange(true))
  508. {
  509. UAVCAN_STM32_LOG("MSR INAK not set");
  510. can_->MCR = bxcan::MCR_RESET;
  511. return -ErrMsrInakNotSet;
  512. }
  513. /*
  514. * Object state - interrupts are disabled, so it's safe to modify it now
  515. */
  516. rx_queue_.reset();
  517. error_cnt_ = 0;
  518. served_aborts_cnt_ = 0;
  519. uavcan::fill_n(pending_tx_, NumTxMailboxes, TxItem());
  520. peak_tx_mailbox_index_ = 0;
  521. had_activity_ = false;
  522. /*
  523. * CAN timings for this bitrate
  524. */
  525. Timings timings;
  526. const int timings_res = computeTimings(bitrate, timings);
  527. if (timings_res < 0)
  528. {
  529. can_->MCR = bxcan::MCR_RESET;
  530. return timings_res;
  531. }
  532. UAVCAN_STM32_LOG("Timings: presc=%u sjw=%u bs1=%u bs2=%u",
  533. unsigned(timings.prescaler), unsigned(timings.sjw), unsigned(timings.bs1), unsigned(timings.bs2));
  534. /*
  535. * Hardware initialization (the hardware has already confirmed initialization mode, see above)
  536. */
  537. can_->MCR = bxcan::MCR_ABOM | bxcan::MCR_AWUM | bxcan::MCR_INRQ; // RM page 648
  538. can_->BTR = ((timings.sjw & 3U) << 24) |
  539. ((timings.bs1 & 15U) << 16) |
  540. ((timings.bs2 & 7U) << 20) |
  541. (timings.prescaler & 1023U) |
  542. ((mode == SilentMode) ? bxcan::BTR_SILM : 0);
  543. can_->IER = bxcan::IER_TMEIE | // TX mailbox empty
  544. bxcan::IER_FMPIE0 | // RX FIFO 0 is not empty
  545. bxcan::IER_FMPIE1; // RX FIFO 1 is not empty
  546. can_->MCR &= ~bxcan::MCR_INRQ; // Leave init mode
  547. if (!waitMsrINakBitStateChange(false))
  548. {
  549. UAVCAN_STM32_LOG("MSR INAK not cleared");
  550. can_->MCR = bxcan::MCR_RESET;
  551. return -ErrMsrInakNotCleared;
  552. }
  553. /*
  554. * Default filter configuration
  555. */
  556. if (self_index_ == 0)
  557. {
  558. can_->FMR |= bxcan::FMR_FINIT;
  559. can_->FMR &= 0xFFFFC0F1;
  560. can_->FMR |= static_cast<uavcan::uint32_t>(NumFilters) << 8; // Slave (CAN2) gets half of the filters
  561. can_->FFA1R = 0; // All assigned to FIFO0 by default
  562. can_->FM1R = 0; // Indentifier Mask mode
  563. #if UAVCAN_STM32_NUM_IFACES > 1
  564. can_->FS1R = 0x7ffffff; // Single 32-bit for all
  565. can_->FilterRegister[0].FR1 = 0; // CAN1 accepts everything
  566. can_->FilterRegister[0].FR2 = 0;
  567. can_->FilterRegister[NumFilters].FR1 = 0; // CAN2 accepts everything
  568. can_->FilterRegister[NumFilters].FR2 = 0;
  569. can_->FA1R = 1 | (1 << NumFilters); // One filter per each iface
  570. #else
  571. can_->FS1R = 0x1fff;
  572. can_->FilterRegister[0].FR1 = 0;
  573. can_->FilterRegister[0].FR2 = 0;
  574. can_->FA1R = 1;
  575. #endif
  576. can_->FMR &= ~bxcan::FMR_FINIT;
  577. }
  578. return 0;
  579. }
  580. void CanIface::handleTxMailboxInterrupt(uavcan::uint8_t mailbox_index, bool txok, const uavcan::uint64_t utc_usec)
  581. {
  582. UAVCAN_ASSERT(mailbox_index < NumTxMailboxes);
  583. had_activity_ = had_activity_ || txok;
  584. TxItem& txi = pending_tx_[mailbox_index];
  585. if (txi.loopback && txok && txi.pending)
  586. {
  587. rx_queue_.push(txi.frame, utc_usec, uavcan::CanIOFlagLoopback);
  588. }
  589. txi.pending = false;
  590. }
  591. void CanIface::handleTxInterrupt(const uavcan::uint64_t utc_usec)
  592. {
  593. // TXOK == false means that there was a hardware failure
  594. if (can_->TSR & bxcan::TSR_RQCP0)
  595. {
  596. const bool txok = can_->TSR & bxcan::TSR_TXOK0;
  597. can_->TSR = bxcan::TSR_RQCP0;
  598. handleTxMailboxInterrupt(0, txok, utc_usec);
  599. }
  600. if (can_->TSR & bxcan::TSR_RQCP1)
  601. {
  602. const bool txok = can_->TSR & bxcan::TSR_TXOK1;
  603. can_->TSR = bxcan::TSR_RQCP1;
  604. handleTxMailboxInterrupt(1, txok, utc_usec);
  605. }
  606. if (can_->TSR & bxcan::TSR_RQCP2)
  607. {
  608. const bool txok = can_->TSR & bxcan::TSR_TXOK2;
  609. can_->TSR = bxcan::TSR_RQCP2;
  610. handleTxMailboxInterrupt(2, txok, utc_usec);
  611. }
  612. update_event_.signalFromInterrupt();
  613. pollErrorFlagsFromISR();
  614. #if UAVCAN_STM32_FREERTOS
  615. update_event_.yieldFromISR();
  616. #endif
  617. }
  618. void CanIface::handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec)
  619. {
  620. UAVCAN_ASSERT(fifo_index < 2);
  621. volatile uavcan::uint32_t* const rfr_reg = (fifo_index == 0) ? &can_->RF0R : &can_->RF1R;
  622. if ((*rfr_reg & bxcan::RFR_FMP_MASK) == 0)
  623. {
  624. UAVCAN_ASSERT(0); // Weird, IRQ is here but no data to read
  625. return;
  626. }
  627. /*
  628. * Register overflow as a hardware error
  629. */
  630. if ((*rfr_reg & bxcan::RFR_FOVR) != 0)
  631. {
  632. error_cnt_++;
  633. }
  634. /*
  635. * Read the frame contents
  636. */
  637. uavcan::CanFrame frame;
  638. const bxcan::RxMailboxType& rf = can_->RxMailbox[fifo_index];
  639. if ((rf.RIR & bxcan::RIR_IDE) == 0)
  640. {
  641. frame.id = uavcan::CanFrame::MaskStdID & (rf.RIR >> 21);
  642. }
  643. else
  644. {
  645. frame.id = uavcan::CanFrame::MaskExtID & (rf.RIR >> 3);
  646. frame.id |= uavcan::CanFrame::FlagEFF;
  647. }
  648. if ((rf.RIR & bxcan::RIR_RTR) != 0)
  649. {
  650. frame.id |= uavcan::CanFrame::FlagRTR;
  651. }
  652. frame.dlc = rf.RDTR & 15;
  653. frame.data[0] = uavcan::uint8_t(0xFF & (rf.RDLR >> 0));
  654. frame.data[1] = uavcan::uint8_t(0xFF & (rf.RDLR >> 8));
  655. frame.data[2] = uavcan::uint8_t(0xFF & (rf.RDLR >> 16));
  656. frame.data[3] = uavcan::uint8_t(0xFF & (rf.RDLR >> 24));
  657. frame.data[4] = uavcan::uint8_t(0xFF & (rf.RDHR >> 0));
  658. frame.data[5] = uavcan::uint8_t(0xFF & (rf.RDHR >> 8));
  659. frame.data[6] = uavcan::uint8_t(0xFF & (rf.RDHR >> 16));
  660. frame.data[7] = uavcan::uint8_t(0xFF & (rf.RDHR >> 24));
  661. *rfr_reg = bxcan::RFR_RFOM | bxcan::RFR_FOVR | bxcan::RFR_FULL; // Release FIFO entry we just read
  662. /*
  663. * Store with timeout into the FIFO buffer and signal update event
  664. */
  665. rx_queue_.push(frame, utc_usec, 0);
  666. #if AP_UAVCAN_SLCAN_ENABLED
  667. _slcan_router.route_frame_to_slcan(this, frame, utc_usec);
  668. #endif
  669. had_activity_ = true;
  670. update_event_.signalFromInterrupt();
  671. pollErrorFlagsFromISR();
  672. #if UAVCAN_STM32_FREERTOS
  673. update_event_.yieldFromISR();
  674. #endif
  675. }
  676. void CanIface::pollErrorFlagsFromISR()
  677. {
  678. const uavcan::uint8_t lec = uavcan::uint8_t((can_->ESR & bxcan::ESR_LEC_MASK) >> bxcan::ESR_LEC_SHIFT);
  679. if (lec != 0)
  680. {
  681. can_->ESR = 0;
  682. error_cnt_++;
  683. // Serving abort requests
  684. for (int i = 0; i < NumTxMailboxes; i++) // Dear compiler, may I suggest you to unroll this loop please.
  685. {
  686. TxItem& txi = pending_tx_[i];
  687. if (txi.pending && txi.abort_on_error)
  688. {
  689. can_->TSR = TSR_ABRQx[i];
  690. txi.pending = false;
  691. served_aborts_cnt_++;
  692. }
  693. }
  694. }
  695. }
  696. void CanIface::discardTimedOutTxMailboxes(uavcan::MonotonicTime current_time)
  697. {
  698. CriticalSectionLocker lock;
  699. for (int i = 0; i < NumTxMailboxes; i++)
  700. {
  701. TxItem& txi = pending_tx_[i];
  702. if (txi.pending && txi.deadline < current_time)
  703. {
  704. can_->TSR = TSR_ABRQx[i]; // Goodnight sweet transmission
  705. txi.pending = false;
  706. error_cnt_++;
  707. }
  708. }
  709. }
  710. bool CanIface::canAcceptNewTxFrame(const uavcan::CanFrame& frame) const
  711. {
  712. /*
  713. * We can accept more frames only if the following conditions are satisfied:
  714. * - There is at least one TX mailbox free (obvious enough);
  715. * - The priority of the new frame is higher than priority of all TX mailboxes.
  716. */
  717. {
  718. static const uavcan::uint32_t TME = bxcan::TSR_TME0 | bxcan::TSR_TME1 | bxcan::TSR_TME2;
  719. const uavcan::uint32_t tme = can_->TSR & TME;
  720. if (tme == TME) // All TX mailboxes are free (as in freedom).
  721. {
  722. return true;
  723. }
  724. if (tme == 0) // All TX mailboxes are busy transmitting.
  725. {
  726. return false;
  727. }
  728. }
  729. /*
  730. * The second condition requires a critical section.
  731. */
  732. CriticalSectionLocker lock;
  733. for (int mbx = 0; mbx < NumTxMailboxes; mbx++)
  734. {
  735. if (pending_tx_[mbx].pending && !frame.priorityHigherThan(pending_tx_[mbx].frame))
  736. {
  737. return false; // There's a mailbox whose priority is higher or equal the priority of the new frame.
  738. }
  739. }
  740. return true; // This new frame will be added to a free TX mailbox in the next @ref send().
  741. }
  742. bool CanIface::isRxBufferEmpty() const
  743. {
  744. CriticalSectionLocker lock;
  745. return rx_queue_.getLength() == 0;
  746. }
  747. uavcan::uint64_t CanIface::getErrorCount() const
  748. {
  749. CriticalSectionLocker lock;
  750. return error_cnt_ + rx_queue_.getOverflowCount();
  751. }
  752. unsigned CanIface::getRxQueueLength() const
  753. {
  754. CriticalSectionLocker lock;
  755. return rx_queue_.getLength();
  756. }
  757. bool CanIface::hadActivity()
  758. {
  759. CriticalSectionLocker lock;
  760. const bool ret = had_activity_;
  761. had_activity_ = false;
  762. return ret;
  763. }
  764. /*
  765. * CanDriver
  766. */
  767. uavcan::CanSelectMasks CanDriver::makeSelectMasks(const uavcan::CanFrame* (& pending_tx)[uavcan::MaxCanIfaces]) const
  768. {
  769. uavcan::CanSelectMasks msk;
  770. for (uavcan::uint8_t i = 0; i < num_ifaces_; i++) {
  771. CanIface* iface = ifaces[if_int_to_gl_index_[i]];
  772. msk.read |= (iface->isRxBufferEmpty() ? 0 : 1) << i;
  773. if (pending_tx[i] != UAVCAN_NULLPTR)
  774. {
  775. msk.write |= (iface->canAcceptNewTxFrame(*pending_tx[i]) ? 1 : 0) << i;
  776. }
  777. }
  778. return msk;
  779. }
  780. bool CanDriver::hasReadableInterfaces() const
  781. {
  782. for (uavcan::uint8_t i = 0; i < num_ifaces_; i++) {
  783. if (!ifaces[if_int_to_gl_index_[i]]->isRxBufferEmpty()) {
  784. return true;
  785. }
  786. }
  787. return false;
  788. }
  789. uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks,
  790. const uavcan::CanFrame* (& pending_tx)[uavcan::MaxCanIfaces],
  791. const uavcan::MonotonicTime blocking_deadline)
  792. {
  793. const uavcan::CanSelectMasks in_masks = inout_masks;
  794. const uavcan::MonotonicTime time = clock::getMonotonic();
  795. for (uavcan::uint8_t i = 0; i < num_ifaces_; i++) {
  796. CanIface* iface = ifaces[if_int_to_gl_index_[i]];
  797. iface->discardTimedOutTxMailboxes(time); // Check TX timeouts - this may release some TX slots
  798. {
  799. CriticalSectionLocker cs_locker;
  800. iface->pollErrorFlagsFromISR();
  801. }
  802. }
  803. inout_masks = makeSelectMasks(pending_tx); // Check if we already have some of the requested events
  804. if ((inout_masks.read & in_masks.read) != 0 ||
  805. (inout_masks.write & in_masks.write) != 0)
  806. {
  807. return 1;
  808. }
  809. (void)update_event_.wait(blocking_deadline - time); // Block until timeout expires or any iface updates
  810. inout_masks = makeSelectMasks(pending_tx); // Return what we got even if none of the requested events are set
  811. return 1; // Return value doesn't matter as long as it is non-negative
  812. }
  813. #if UAVCAN_STM32_BAREMETAL || UAVCAN_STM32_FREERTOS
  814. static void nvicEnableVector(IRQn_Type irq, uint8_t prio)
  815. {
  816. #if !defined (USE_HAL_DRIVER)
  817. NVIC_InitTypeDef NVIC_InitStructure;
  818. NVIC_InitStructure.NVIC_IRQChannel = irq;
  819. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = prio;
  820. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  821. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  822. NVIC_Init(&NVIC_InitStructure);
  823. #else
  824. HAL_NVIC_SetPriority(irq, prio, 0);
  825. HAL_NVIC_EnableIRQ(irq);
  826. #endif
  827. }
  828. #endif
  829. void CanDriver::initOnce()
  830. {
  831. /*
  832. * CAN1, CAN2
  833. */
  834. {
  835. CriticalSectionLocker lock;
  836. RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
  837. RCC->APB1RSTR |= RCC_APB1RSTR_CAN1RST;
  838. RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN1RST;
  839. # if UAVCAN_STM32_NUM_IFACES > 1
  840. RCC->APB1ENR |= RCC_APB1ENR_CAN2EN;
  841. RCC->APB1RSTR |= RCC_APB1RSTR_CAN2RST;
  842. RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN2RST;
  843. # endif
  844. }
  845. /*
  846. * IRQ
  847. */
  848. {
  849. CriticalSectionLocker lock;
  850. nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  851. nvicEnableVector(CAN1_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  852. nvicEnableVector(CAN1_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  853. # if UAVCAN_STM32_NUM_IFACES > 1
  854. nvicEnableVector(CAN2_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  855. nvicEnableVector(CAN2_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  856. nvicEnableVector(CAN2_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  857. # endif
  858. }
  859. }
  860. int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode)
  861. {
  862. int res = 0;
  863. UAVCAN_STM32_LOG("Bitrate %lu mode %d", static_cast<unsigned long>(bitrate), static_cast<int>(mode));
  864. static bool initialized_once = false;
  865. if (!initialized_once)
  866. {
  867. initialized_once = true;
  868. UAVCAN_STM32_LOG("First initialization");
  869. initOnce();
  870. }
  871. /*
  872. * CAN1
  873. */
  874. UAVCAN_STM32_LOG("Initing iface 0...");
  875. ifaces[0] = &if0_; // This link must be initialized first,
  876. res = if0_.init(bitrate, mode); // otherwise an IRQ may fire while the interface is not linked yet;
  877. if (res < 0) // a typical race condition.
  878. {
  879. UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
  880. ifaces[0] = UAVCAN_NULLPTR;
  881. goto fail;
  882. }
  883. /*
  884. * CAN2
  885. */
  886. #if UAVCAN_STM32_NUM_IFACES > 1
  887. UAVCAN_STM32_LOG("Initing iface 1...");
  888. ifaces[1] = &if1_; // Same thing here.
  889. res = if1_.init(bitrate, mode);
  890. if (res < 0)
  891. {
  892. UAVCAN_STM32_LOG("Iface 1 init failed %i", res);
  893. ifaces[1] = UAVCAN_NULLPTR;
  894. goto fail;
  895. }
  896. #endif
  897. UAVCAN_STM32_LOG("CAN drv init OK");
  898. UAVCAN_ASSERT(res >= 0);
  899. return res;
  900. fail:
  901. UAVCAN_STM32_LOG("CAN drv init failed %i", res);
  902. UAVCAN_ASSERT(res < 0);
  903. return res;
  904. }
  905. void CanDriver::initOnce(uavcan::uint8_t can_number, bool enable_irqs)
  906. {
  907. /*
  908. * CAN1, CAN2
  909. */
  910. {
  911. CriticalSectionLocker lock;
  912. if (can_number == 0) {
  913. RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
  914. RCC->APB1RSTR |= RCC_APB1RSTR_CAN1RST;
  915. RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN1RST;
  916. }
  917. # if UAVCAN_STM32_NUM_IFACES > 1
  918. else if (can_number == 1) {
  919. RCC->APB1ENR |= RCC_APB1ENR_CAN2EN;
  920. RCC->APB1RSTR |= RCC_APB1RSTR_CAN2RST;
  921. RCC->APB1RSTR &= ~RCC_APB1RSTR_CAN2RST;
  922. }
  923. # endif
  924. }
  925. if (!enable_irqs) {
  926. return;
  927. }
  928. /*
  929. * IRQ
  930. */
  931. {
  932. CriticalSectionLocker lock;
  933. if (can_number == 0) {
  934. nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  935. nvicEnableVector(CAN1_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  936. nvicEnableVector(CAN1_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  937. }
  938. # if UAVCAN_STM32_NUM_IFACES > 1
  939. else if (can_number == 1) {
  940. nvicEnableVector(CAN2_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  941. nvicEnableVector(CAN2_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  942. nvicEnableVector(CAN2_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
  943. }
  944. # endif
  945. }
  946. }
  947. int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode, uavcan::uint8_t can_number)
  948. {
  949. int res = 0;
  950. UAVCAN_STM32_LOG("Bitrate %lu mode %d", static_cast<unsigned long>(bitrate), static_cast<int>(mode));
  951. if (can_number > UAVCAN_STM32_NUM_IFACES) {
  952. res = -1;
  953. goto fail;
  954. }
  955. static bool initialized_once[UAVCAN_STM32_NUM_IFACES] = {false};
  956. if (!initialized_once[can_number]) {
  957. initialized_once[can_number] = true;
  958. initialized_by_me_[can_number] = true;
  959. if (can_number == 1 && !initialized_once[0]) {
  960. UAVCAN_STM32_LOG("Iface 0 is not initialized yet but we need it for Iface 1, trying to init it");
  961. UAVCAN_STM32_LOG("Enabling CAN iface 0");
  962. initOnce(0, false);
  963. UAVCAN_STM32_LOG("Initing iface 0...");
  964. res = if0_.init(bitrate, mode);
  965. if (res < 0) {
  966. UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
  967. goto fail;
  968. }
  969. }
  970. UAVCAN_STM32_LOG("Enabling CAN iface %d", can_number);
  971. initOnce(can_number, true);
  972. } else if (!initialized_by_me_[can_number]) {
  973. UAVCAN_STM32_LOG("CAN iface %d initialized in another CANDriver!", can_number);
  974. res = -2;
  975. goto fail;
  976. }
  977. if (can_number == 0) {
  978. /*
  979. * CAN1
  980. */
  981. UAVCAN_STM32_LOG("Initing iface 0...");
  982. ifaces[0] = &if0_; // This link must be initialized first,
  983. res = if0_.init(bitrate, mode); // otherwise an IRQ may fire while the interface is not linked yet;
  984. if (res < 0) // a typical race condition.
  985. {
  986. UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
  987. ifaces[0] = UAVCAN_NULLPTR;
  988. goto fail;
  989. }
  990. } else if (can_number == 1) {
  991. /*
  992. * CAN2
  993. */
  994. #if UAVCAN_STM32_NUM_IFACES > 1
  995. UAVCAN_STM32_LOG("Initing iface 1...");
  996. ifaces[1] = &if1_; // Same thing here.
  997. res = if1_.init(bitrate, mode);
  998. if (res < 0)
  999. {
  1000. UAVCAN_STM32_LOG("Iface 1 init failed %i", res);
  1001. ifaces[1] = UAVCAN_NULLPTR;
  1002. goto fail;
  1003. }
  1004. #endif
  1005. }
  1006. if_int_to_gl_index_[num_ifaces_++] = can_number;
  1007. UAVCAN_STM32_LOG("CAN drv init OK");
  1008. UAVCAN_ASSERT(res >= 0);
  1009. return res;
  1010. fail:
  1011. UAVCAN_STM32_LOG("CAN drv init failed %i", res);
  1012. UAVCAN_ASSERT(res < 0);
  1013. return res;
  1014. }
  1015. CanIface* CanDriver::getIface(uavcan::uint8_t iface_index)
  1016. {
  1017. if (iface_index < num_ifaces_)
  1018. {
  1019. return ifaces[if_int_to_gl_index_[iface_index]];
  1020. }
  1021. return UAVCAN_NULLPTR;
  1022. }
  1023. bool CanDriver::hadActivity()
  1024. {
  1025. for (uavcan::uint8_t i = 0; i < num_ifaces_; i++) {
  1026. if (ifaces[if_int_to_gl_index_[i]]->hadActivity()) {
  1027. return true;
  1028. }
  1029. }
  1030. return false;
  1031. }
  1032. } // namespace uavcan_stm32
  1033. /*
  1034. * Interrupt handlers
  1035. */
  1036. extern "C"
  1037. {
  1038. UAVCAN_STM32_IRQ_HANDLER(CAN1_TX_IRQHandler);
  1039. UAVCAN_STM32_IRQ_HANDLER(CAN1_TX_IRQHandler)
  1040. {
  1041. UAVCAN_STM32_IRQ_PROLOGUE();
  1042. ChibiOS_CAN::handleTxInterrupt(0);
  1043. UAVCAN_STM32_IRQ_EPILOGUE();
  1044. }
  1045. UAVCAN_STM32_IRQ_HANDLER(CAN1_RX0_IRQHandler);
  1046. UAVCAN_STM32_IRQ_HANDLER(CAN1_RX0_IRQHandler)
  1047. {
  1048. UAVCAN_STM32_IRQ_PROLOGUE();
  1049. ChibiOS_CAN::handleRxInterrupt(0, 0);
  1050. UAVCAN_STM32_IRQ_EPILOGUE();
  1051. }
  1052. UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler);
  1053. UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler)
  1054. {
  1055. UAVCAN_STM32_IRQ_PROLOGUE();
  1056. ChibiOS_CAN::handleRxInterrupt(0, 1);
  1057. UAVCAN_STM32_IRQ_EPILOGUE();
  1058. }
  1059. # if UAVCAN_STM32_NUM_IFACES > 1
  1060. #if !defined(CAN2_TX_IRQHandler)
  1061. # error "Misconfigured build1"
  1062. #endif
  1063. #if !defined(CAN2_RX0_IRQHandler)
  1064. # error "Misconfigured build2"
  1065. #endif
  1066. #if !defined(CAN2_RX1_IRQHandler)
  1067. # error "Misconfigured build3"
  1068. #endif
  1069. UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler);
  1070. UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler)
  1071. {
  1072. UAVCAN_STM32_IRQ_PROLOGUE();
  1073. ChibiOS_CAN::handleTxInterrupt(1);
  1074. UAVCAN_STM32_IRQ_EPILOGUE();
  1075. }
  1076. UAVCAN_STM32_IRQ_HANDLER(CAN2_RX0_IRQHandler);
  1077. UAVCAN_STM32_IRQ_HANDLER(CAN2_RX0_IRQHandler)
  1078. {
  1079. UAVCAN_STM32_IRQ_PROLOGUE();
  1080. ChibiOS_CAN::handleRxInterrupt(1, 0);
  1081. UAVCAN_STM32_IRQ_EPILOGUE();
  1082. }
  1083. UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler);
  1084. UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler)
  1085. {
  1086. UAVCAN_STM32_IRQ_PROLOGUE();
  1087. ChibiOS_CAN::handleRxInterrupt(1, 1);
  1088. UAVCAN_STM32_IRQ_EPILOGUE();
  1089. }
  1090. # endif
  1091. } // extern "C"
  1092. #endif //!defined(STM32H7XX)
  1093. #endif //HAL_WITH_UAVCAN