Skip to content

Commit 1a2d624

Browse files
committed
Added Raw CAN (unlocked can read api) and updated the code for the
rxInterrupt to work for all CAN instances
1 parent 033b08d commit 1a2d624

File tree

12 files changed

+126
-7
lines changed

12 files changed

+126
-7
lines changed

drivers/include/drivers/RawCAN.h

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2019 ARM Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef RAWCAN_H
19+
#define RAWCAN_H
20+
21+
#include "platform/platform.h"
22+
#include "drivers/CAN.h"
23+
24+
#if DEVICE_CAN || defined(DOXYGEN_ONLY)
25+
26+
#include "interfaces/InterfaceCAN.h"
27+
#include "hal/can_api.h"
28+
#include "platform/Callback.h"
29+
#include "platform/PlatformMutex.h"
30+
31+
namespace mbed {
32+
class RawCAN: public CAN {
33+
public:
34+
RawCAN(PinName rd, PinName td);
35+
36+
/** Initialize CAN interface and set the frequency
37+
*
38+
* @param rd the read pin
39+
* @param td the transmit pin
40+
* @param hz the bus frequency in hertz
41+
*/
42+
RawCAN(PinName rd, PinName td, int hz);
43+
44+
/** Initialize CAN interface
45+
*
46+
* @param pinmap reference to structure which holds static pinmap
47+
* @param td the transmit pin
48+
* @param hz the bus frequency in hertz
49+
*/
50+
51+
virtual ~RawCAN() {};
52+
53+
/** Read a CANMessage from the bus.
54+
*
55+
* @param msg A CANMessage to read to.
56+
* @param handle message filter handle (0 for any message)
57+
*
58+
* @returns
59+
* 0 if no message arrived,
60+
* 1 if message arrived
61+
*/
62+
int read(CANMessage &msg, int handle = 0);
63+
64+
};
65+
} //namespace mbed
66+
67+
#endif
68+
69+
#endif //RAWCAN_H

drivers/source/RawCAN.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2019 ARM Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "drivers/RawCan.h"
19+
20+
#if DEVICE_CAN
21+
22+
#include "platform/mbed_power_mgmt.h"
23+
24+
namespace mbed {
25+
RawCAN::RawCAN(PinName rd, PinName td): CAN(rd, td) {}
26+
27+
RawCAN::RawCAN(PinName rd, PinName td, int hz): CAN(rd, td, hz) {}
28+
29+
/* There are situations where the RX interrupt of CAN are cleared only by
30+
* CAN read operations and locks are not allowed in ISR context in mbed
31+
* hence this provides an unlocked read to resolve such problem without
32+
* any effect on the performance. This will work only in case of a single
33+
* thread accessing a CAN instance, multiple threads will lead to race conditions
34+
*/
35+
int RawCAN::read(CANMessage &msg, int handle){
36+
int ret = can_read(&_can, &msg, handle);
37+
return ret;
38+
}
39+
40+
} // namespace
41+
#endif //DEVICE_CAN

mbed.h

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#include "drivers/I2C.h"
6969
#include "drivers/I2CSlave.h"
7070
#include "drivers/CAN.h"
71+
#include "drivers/RawCAN.h"
7172
#include "drivers/UnbufferedSerial.h"
7273
#include "drivers/BufferedSerial.h"
7374
#include "drivers/FlashIAP.h"

targets/TARGET_STM/TARGET_STM32F0/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ struct can_s {
152152
CAN_HandleTypeDef CanHandle;
153153
int index;
154154
int hz;
155+
int rxIrqStatus;
155156
};
156157
#endif
157158

targets/TARGET_STM/TARGET_STM32F1/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct can_s {
142142
CAN_HandleTypeDef CanHandle;
143143
int index;
144144
int hz;
145+
int rxIrqStatus;
145146
};
146147
#endif
147148

targets/TARGET_STM/TARGET_STM32F2/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ struct can_s {
151151
CAN_HandleTypeDef CanHandle;
152152
int index;
153153
int hz;
154+
int rxIrqStatus;
154155
};
155156
#endif
156157

targets/TARGET_STM/TARGET_STM32F3/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ struct can_s {
139139
CAN_HandleTypeDef CanHandle;
140140
int index;
141141
int hz;
142+
int rxIrqStatus;
142143
};
143144
#endif
144145

targets/TARGET_STM/TARGET_STM32F4/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ struct can_s {
154154
CAN_HandleTypeDef CanHandle;
155155
int index;
156156
int hz;
157+
int rxIrqStatus;
157158
};
158159
#endif
159160

targets/TARGET_STM/TARGET_STM32F7/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ struct can_s {
163163
CAN_HandleTypeDef CanHandle;
164164
int index;
165165
int hz;
166+
int rxIrqStatus;
166167
};
167168
#endif
168169

targets/TARGET_STM/TARGET_STM32L4/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ struct can_s {
153153
CAN_HandleTypeDef CanHandle;
154154
int index;
155155
int hz;
156+
int rxIrqStatus;
156157
};
157158
#endif
158159

targets/TARGET_STM/TARGET_STM32L5/objects.h

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ struct can_s {
153153
CAN_HandleTypeDef CanHandle;
154154
int index;
155155
int hz;
156+
int rxIrqStatus;
156157
};
157158
#endif
158159

targets/TARGET_STM/can_api.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,6 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
651651

652652
static uint32_t can_irq_ids[CAN_NUM] = {0};
653653
static can_irq_handler irq_handler;
654-
static uint32_t rx_irq_status = DISABLED;
655654

656655
static void can_registers_init(can_t *obj)
657656
{
@@ -762,6 +761,7 @@ void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
762761
{
763762
irq_handler = handler;
764763
can_irq_ids[obj->index] = id;
764+
obj->rxIrqStatus = false;
765765
}
766766

767767
void can_irq_free(can_t *obj)
@@ -771,7 +771,7 @@ void can_irq_free(can_t *obj)
771771
can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \
772772
CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF);
773773
can_irq_ids[obj->index] = 0;
774-
rx_irq_status = DISABLED;
774+
obj->rxIrqStatus = DISABLED;
775775
}
776776

777777
void can_free(can_t *obj)
@@ -1003,7 +1003,7 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
10031003
can->RF1R |= CAN_RF1R_RFOM1;
10041004
}
10051005

1006-
if(rx_irq_status == ENABLED) {
1006+
if(obj->rxIrqStatus == ENABLED) {
10071007
__HAL_CAN_ENABLE_IT(&obj->CanHandle, CAN_IT_FMP0);
10081008
}
10091009

@@ -1020,7 +1020,7 @@ void can_reset(can_t *obj)
10201020

10211021
/* restore registers state as saved in obj context */
10221022
can_registers_init(obj);
1023-
rx_irq_status = DISABLED;
1023+
obj->rxIrqStatus = DISABLED;
10241024
}
10251025

10261026
unsigned char can_rderror(can_t *obj)
@@ -1276,7 +1276,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
12761276
ier = CAN_IT_FMP0;
12771277
irq_n = CAN1_IRQ_RX_IRQN;
12781278
vector = (uint32_t)&CAN1_IRQ_RX_VECT;
1279-
rx_irq_status = ENABLED;
1279+
obj->rxIrqStatus = ENABLED;
12801280
break;
12811281
case IRQ_TX:
12821282
ier = CAN_IT_TME;
@@ -1309,7 +1309,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
13091309
ier = CAN_IT_FMP0;
13101310
irq_n = CAN2_IRQ_RX_IRQN;
13111311
vector = (uint32_t)&CAN2_IRQ_RX_VECT;
1312-
rx_irq_status = ENABLED;
1312+
obj->rxIrqStatus = ENABLED;
13131313
break;
13141314
case IRQ_TX:
13151315
ier = CAN_IT_TME;
@@ -1343,7 +1343,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
13431343
ier = CAN_IT_FMP0;
13441344
irq_n = CAN3_IRQ_RX_IRQN;
13451345
vector = (uint32_t)&CAN3_IRQ_RX_VECT;
1346-
rx_irq_status = ENABLED;
1346+
obj->rxIrqStatus = ENABLED;
13471347
break;
13481348
case IRQ_TX:
13491349
ier = CAN_IT_TME;

0 commit comments

Comments
 (0)