Controller Area Network library for NUCLEO boards equipped with CAN peripheral.

Dependents:   Nucleo-Courtois CANBLE CANnucleo_Hello3 Nucleo_Serialprintf ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CANnucleo.cpp Source File

CANnucleo.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  * Modified by Zoltan Hudak    <hudakz@outlook.com>
00017  *
00018  */
00019 #include "CANnucleo.h"
00020 #include "cmsis.h"
00021 
00022 /**
00023  * @brief   Constructor
00024  * @note    Constructs an instance of CAN class
00025  * @param   rxPin: CAN Rx pin name
00026  * @param   txPin: CAN Tx pin name
00027  * @param   abom:  Automatic recovery from bus-off state (defaults to enabled)
00028  * @retval
00029  */
00030 CAN::CAN(PinName rxPin, PinName txPin, FunctionalState abom /* = ENABLE */) :
00031     _irq() {
00032     can_init(rxPin, txPin, abom);
00033     can_irq_init((uint32_t)this, (&CAN::_irq_handler ));
00034 }
00035 
00036 /**
00037  * @brief
00038  * @note
00039  * @param
00040  * @retval
00041  */
00042 CAN::~CAN (void) {
00043     can_irq_free();
00044     can_free();
00045 }
00046 
00047 /**
00048  * @brief
00049  * @note
00050  * @param
00051  * @retval
00052  */
00053 int CAN::frequency(int f) {
00054     lock();
00055     int ret = can_frequency(f);
00056     unlock();
00057     return ret;
00058 }
00059 
00060 /**
00061  * @brief
00062  * @note
00063  * @param
00064  * @retval
00065  */
00066 int CAN::write(CANMessage msg) {
00067     lock();
00068     int ret = can_write(msg, 0);
00069     unlock();
00070     return ret;
00071 }
00072 
00073 /**
00074  * @brief
00075  * @note
00076  * @param
00077  * @retval
00078  */
00079 int CAN::read(CANMessage& msg, int handle) {
00080     lock();
00081     int ret = can_read(&msg, handle);
00082     unlock();
00083     return ret;
00084 }
00085 
00086 /**
00087  * @brief
00088  * @note
00089  * @param
00090  * @retval
00091  */
00092 void CAN::reset(void) {
00093     lock();
00094     can_reset();
00095     unlock();
00096 }
00097 
00098 /**
00099  * @brief
00100  * @note
00101  * @param
00102  * @retval
00103  */
00104 unsigned char CAN::rderror(void) {
00105     lock();
00106     unsigned char ret = can_rderror();
00107     unlock();
00108     return ret;
00109 }
00110 
00111 /**
00112  * @brief
00113  * @note
00114  * @param
00115  * @retval
00116  */
00117 unsigned char CAN::tderror(void) {
00118     lock();
00119     unsigned char ret = can_tderror();
00120     unlock();
00121     return ret;
00122 }
00123 
00124 /**
00125  * @brief
00126  * @note
00127  * @param
00128  * @retval
00129  */
00130 void CAN::monitor(bool silent) {
00131     lock();
00132     can_monitor((silent) ? 1 : 0);
00133     unlock();
00134 }
00135 
00136 /**
00137  * @brief
00138  * @note
00139  * @param
00140  * @retval
00141  */
00142 int CAN::mode(Mode mode) {
00143     lock();
00144     int ret = can_mode((CanMode) mode);
00145     unlock();
00146     return ret;
00147 }
00148 
00149 /**
00150  * @brief   Sets up a CAN filter
00151  * @note    At the present, CANnucleo supports only mask mode and 32-bit filter scale.
00152  *          Identifier list mode filtering and 16-bit filter scale are not supported.
00153  *          There are 14 filters available (0 - 13) for the application to set up.
00154  *          Each filter is a 32-bit filter defined by a filter ID and a filter mask.
00155  *          If no filter is set up then no CAN message is accepted (received)!
00156  *          That's why filter #0 is set up in the constructor to receive all CAN messages by default.
00157  *          On reception of a message it is compared with filter #0. If there is a match, the message is stored.
00158  *          If there is no match, the incoming identifier is then compared with the next filter.
00159  *          If the received identifier does not match any of the identifiers configured in the filters,
00160  *          the message is discarded by hardware without disturbing the software.
00161  *
00162  * @param   id: 'Filter ID' defines the bit values to be compared with the corresponding received bits
00163  *
00164  * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] |  EXID[4:0] IDE RTR 0 |
00165  *
00166  * STID - Stardard Identifier bits
00167  * EXID - Extended Identifier bits
00168  * [x:y]- bit range
00169  * IDE  - Identifier Extension bit (0 -> Standard Identifier, 1 -> Extended Identifier)
00170  * RTR  - Remote Transmission Request bit (0 -> Remote Transmission Request, 1 -> Standard message)
00171  *
00172  * @param   mask: 'Filter mask' defines which bits of the 'Filter ID' are compared with the received bits
00173  *                and which bits are disregarded.
00174 
00175  * Mapping of 32-bits (4-bytes) : | STID[10:3] | STID[2:0] EXID[17:13] | EXID[12:5] |  EXID[4:0] IDE RTR 0 |
00176  *
00177  * STID - Stardard Identifier bits
00178  * EXID - Extended Identifier bits
00179  * [x:y]- bit range
00180  * IDE  - Identifier Extension bit
00181  * RTR  - Remote Transmission Request bit
00182  *
00183  * 1 -> bit is considered
00184  * 0 -> bit is disregarded
00185  *
00186  * ----------------------------------------
00187  * Example of filter set up and filtering:
00188  * ----------------------------------------
00189 *
00190  * Let's assume we would like to receive only messages 
00191  * with standard identifier STID = 0x0207  (STID[15:0] = 00000010 00000111)
00192  *
00193  * We map the STID to filter ID by shifting the bits appropriately:
00194  * Filter id = STID << (16 + (15 - 10)) = STID << 21 = 01000000 11100000 00000000 00000000 = 0x40E00000
00195  *
00196  * To compare only the bits representing STID we set the filter mask adequately:
00197  * Filter mask = 11111111 11100000 00000000 00000100 = 0xFFE00004
00198  *               |||||||| |||                    |
00199  *               -------- ---                    |
00200  *                   |     |                     |
00201  *            STID[10:3]  STID[2:0]             IDE   
00202  *
00203  * Recall that filter #0 has been set up in the constructor to receive all CAN messages by default.
00204  * So we have to reconfigure it. If we were set up filter #1 here then filter #0 would receive all the messages
00205  * and no message would reach filter #1!
00206  *
00207  * To reconfigure (set up) filter #0 we call:
00208  *     can.filter(0x0207 << 21, 0xFFE00004, CANAny, 0);
00209  *
00210  *             Only these bits of 'Filter id' (set to 1 here in 'Filter mask') are compared with the corresponding
00211  *             bits of received message (the others are disregarded)
00212  *                                |
00213  *                 ---------------------------------
00214  *                 |||||||| |||                    |
00215  *   Filter mask = 11111111 11100000 00000000 00000100 (= 0xFFE00004)
00216  *   Filter id   = 01000000 11100000 00000000 00000000 (= 0x40E00000)
00217  *                 |||||||| |||                    |
00218  *                 ---------------------------------
00219  *                                |
00220  *            To receive the message the values of these bits must match.
00221  *            Otherwise the message is passed to the next filter or
00222  *            discarded if this was the last active filter.
00223  *                                |
00224  *                 ---------------------------------
00225  *                 |||||||| |||                    |
00226  *   Received id = 01000000 11100000 00000000 00000010 (= 0x40E00002)
00227  *                             ||||| |||||||| ||||| ||
00228  *                             -----------------------
00229  *                                         |
00230  *                          These bits (set to 0 in 'Filter mask') are disregarded (masked).
00231  *                          They can have arbitrary values.
00232  *
00233  * NOTE: For the meaning of individual bits see the mapping of 32-bits explained above.
00234  *
00235  * @param   format: This parameter must be CANAny
00236  * @param   handle: Selects the filter. This parameter must be a number between 0 and 13.
00237  * @retval  0 - successful
00238  *          1 - error
00239  *          2 - busy
00240  *          3 - time out  
00241  */
00242 int CAN::filter(unsigned int id, unsigned int mask, CANFormat format /* = CANAny */, int handle /* = 0 */) {
00243     lock();
00244     int ret = can_filter(id, mask, format, handle);
00245     unlock();
00246     return ret;
00247 }
00248 
00249 /**
00250  * @brief   Attaches handler funcion to CAN1 RX0 Interrupt
00251  * @note    Only CAN1 RX0 Interrupt supported
00252  * @param   fptr: pointer to a void (*)(void) function
00253  * @param   type: not used (only CAN1 RX0 Interrupt supported) 
00254  * @retval
00255  */
00256 void CAN::attach(mbed::Callback<void()> func, IrqType type) {
00257     lock();
00258     HAL_NVIC_DisableIRQ(CAN_IRQ);
00259     if (func)
00260         _irq[(CanIrqType)type] = func;
00261     HAL_NVIC_EnableIRQ(CAN_IRQ);
00262     unlock();
00263 }
00264 
00265 /**
00266  * @brief
00267  * @note
00268  * @param
00269  * @retval
00270  */
00271 void CAN::_irq_handler (uint32_t id, CanIrqType type) {
00272     CAN*    handler = (CAN*)id;
00273     handler->_irq[type].call();
00274 }
00275 
00276 void CAN::lock() {
00277     _mutex.lock();
00278 }
00279 
00280 void CAN::unlock() {
00281     _mutex.unlock();
00282 }
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294