Skip to content

Commit be07771

Browse files
committed
Implement polymorphism for CAN
1 parent 684e192 commit be07771

File tree

3 files changed

+184
-104
lines changed

3 files changed

+184
-104
lines changed

drivers/include/drivers/CAN.h

Lines changed: 12 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -21,91 +21,13 @@
2121

2222
#if DEVICE_CAN || defined(DOXYGEN_ONLY)
2323

24+
#include "interfaces/InterfaceCAN.h"
2425
#include "hal/can_api.h"
2526
#include "platform/Callback.h"
2627
#include "platform/PlatformMutex.h"
2728
#include "platform/NonCopyable.h"
2829

2930
namespace mbed {
30-
/** \defgroup drivers-public-api-can CAN
31-
* \ingroup drivers-public-api
32-
*/
33-
34-
/**
35-
* \defgroup drivers_CANMessage CANMessage class
36-
* \ingroup drivers-public-api-can
37-
* @{
38-
*/
39-
40-
/** CANMessage class
41-
*
42-
* @note Synchronization level: Thread safe
43-
*/
44-
class CANMessage : public CAN_Message {
45-
46-
public:
47-
/** Creates empty CAN message.
48-
*/
49-
CANMessage() : CAN_Message()
50-
{
51-
len = 8U;
52-
type = CANData;
53-
format = CANStandard;
54-
id = 0U;
55-
memset(data, 0, 8);
56-
}
57-
58-
/** Creates CAN message with specific content.
59-
*
60-
* @param _id Message ID
61-
* @param _data Mesaage Data
62-
* @param _len Message Data length
63-
* @param _type Type of Data: Use enum CANType for valid parameter values
64-
* @param _format Data Format: Use enum CANFormat for valid parameter values
65-
*/
66-
CANMessage(unsigned int _id, const unsigned char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard)
67-
{
68-
len = (_len > 8) ? 8 : _len;
69-
type = _type;
70-
format = _format;
71-
id = _id;
72-
memcpy(data, _data, len);
73-
}
74-
75-
76-
/** Creates CAN message with specific content.
77-
*
78-
* @param _id Message ID
79-
* @param _data Mesaage Data
80-
* @param _len Message Data length
81-
* @param _type Type of Data: Use enum CANType for valid parameter values
82-
* @param _format Data Format: Use enum CANFormat for valid parameter values
83-
*/
84-
CANMessage(unsigned int _id, const char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard)
85-
{
86-
len = (_len > 8) ? 8 : _len;
87-
type = _type;
88-
format = _format;
89-
id = _id;
90-
memcpy(data, _data, len);
91-
}
92-
93-
/** Creates CAN remote message.
94-
*
95-
* @param _id Message ID
96-
* @param _format Data Format: Use enum CANType for valid parameter values
97-
*/
98-
CANMessage(unsigned int _id, CANFormat _format = CANStandard)
99-
{
100-
len = 0;
101-
type = CANRemote;
102-
format = _format;
103-
id = _id;
104-
memset(data, 0, 8);
105-
}
106-
};
107-
108-
/** @}*/
10931

11032
/**
11133
* \defgroup drivers_CAN CAN class
@@ -115,7 +37,13 @@ class CANMessage : public CAN_Message {
11537

11638
/** A can bus client, used for communicating with can devices
11739
*/
118-
class CAN : private NonCopyable<CAN> {
40+
class CAN
41+
#ifdef FEATURE_EXPERIMENTAL_API
42+
final : public interface::CAN, private NonCopyable<CAN>
43+
#else
44+
: private NonCopyable<CAN>
45+
#endif
46+
{
11947

12048
public:
12149
/** Creates a CAN interface connected to specific pins.
@@ -233,14 +161,7 @@ class CAN : private NonCopyable<CAN> {
233161
*/
234162
void monitor(bool silent);
235163

236-
enum Mode {
237-
Reset = 0,
238-
Normal,
239-
Silent,
240-
LocalTest,
241-
GlobalTest,
242-
SilentTest
243-
};
164+
using Mode = ::mbed::interface::can::Mode;
244165

245166
/** Change CAN operation to the specified mode
246167
*
@@ -277,19 +198,7 @@ class CAN : private NonCopyable<CAN> {
277198
*/
278199
unsigned char tderror();
279200

280-
enum IrqType {
281-
RxIrq = 0,
282-
TxIrq,
283-
EwIrq,
284-
DoIrq,
285-
WuIrq,
286-
EpIrq,
287-
AlIrq,
288-
BeIrq,
289-
IdIrq,
290-
291-
IrqCnt
292-
};
201+
using IrqType = ::mbed::interface::can::IrqType;
293202

294203
/** Attach a function to call whenever a CAN frame received interrupt is
295204
* generated.
@@ -299,7 +208,7 @@ class CAN : private NonCopyable<CAN> {
299208
* @param func A pointer to a void function, or 0 to set as none
300209
* @param type Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, CAN::TxIrq for transmitted or aborted, CAN::EwIrq for error warning, CAN::DoIrq for data overrun, CAN::WuIrq for wake-up, CAN::EpIrq for error passive, CAN::AlIrq for arbitration lost, CAN::BeIrq for bus error)
301210
*/
302-
void attach(Callback<void()> func, IrqType type = RxIrq);
211+
void attach(Callback<void()> func, IrqType type = IrqType::RxIrq);
303212

304213
static void _irq_handler(uint32_t id, CanIrqType type);
305214

@@ -309,7 +218,7 @@ class CAN : private NonCopyable<CAN> {
309218
virtual void unlock();
310219

311220
can_t _can;
312-
Callback<void()> _irq[IrqCnt];
221+
Callback<void()> _irq[IrqType::IrqCnt];
313222
PlatformMutex _mutex;
314223
#endif
315224
};
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
* Mbed-OS Microcontroller Library
3+
* Copyright (c) 2021 Embedded Planet
4+
* Copyright (c) 2021 ARM Limited
5+
* SPDX-License-Identifier: Apache-2.0
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License
18+
*/
19+
20+
#ifndef MBED_INTERFACE_CAN_H_
21+
#define MBED_INTERFACE_CAN_H_
22+
23+
#include "hal/can_helper.h"
24+
25+
#include <cstring>
26+
27+
#include "platform/Callback.h"
28+
29+
namespace mbed {
30+
31+
// Forward declare CAN
32+
class CAN;
33+
34+
/** \defgroup drivers-public-api-can CAN
35+
* \ingroup drivers-public-api
36+
*/
37+
38+
/**
39+
* \defgroup drivers_CANMessage CANMessage class
40+
* \ingroup drivers-public-api-can
41+
* @{
42+
*/
43+
44+
/** CANMessage class
45+
*
46+
* @note Synchronization level: Thread safe
47+
*/
48+
class CANMessage : public CAN_Message {
49+
50+
public:
51+
/** Creates empty CAN message.
52+
*/
53+
CANMessage() : CAN_Message()
54+
{
55+
len = 8U;
56+
type = CANData;
57+
format = CANStandard;
58+
id = 0U;
59+
memset(data, 0, 8);
60+
}
61+
62+
/** Creates CAN message with specific content.
63+
*
64+
* @param _id Message ID
65+
* @param _data Mesaage Data
66+
* @param _len Message Data length
67+
* @param _type Type of Data: Use enum CANType for valid parameter values
68+
* @param _format Data Format: Use enum CANFormat for valid parameter values
69+
*/
70+
CANMessage(unsigned int _id, const unsigned char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard)
71+
{
72+
len = (_len > 8) ? 8 : _len;
73+
type = _type;
74+
format = _format;
75+
id = _id;
76+
memcpy(data, _data, len);
77+
}
78+
79+
80+
/** Creates CAN message with specific content.
81+
*
82+
* @param _id Message ID
83+
* @param _data Mesaage Data
84+
* @param _len Message Data length
85+
* @param _type Type of Data: Use enum CANType for valid parameter values
86+
* @param _format Data Format: Use enum CANFormat for valid parameter values
87+
*/
88+
CANMessage(unsigned int _id, const char *_data, unsigned char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard)
89+
{
90+
len = (_len > 8) ? 8 : _len;
91+
type = _type;
92+
format = _format;
93+
id = _id;
94+
memcpy(data, _data, len);
95+
}
96+
97+
/** Creates CAN remote message.
98+
*
99+
* @param _id Message ID
100+
* @param _format Data Format: Use enum CANType for valid parameter values
101+
*/
102+
CANMessage(unsigned int _id, CANFormat _format = CANStandard)
103+
{
104+
len = 0;
105+
type = CANRemote;
106+
format = _format;
107+
id = _id;
108+
memset(data, 0, 8);
109+
}
110+
};
111+
112+
/** @}*/
113+
114+
namespace interface {
115+
116+
namespace can {
117+
118+
enum Mode {
119+
Reset = 0,
120+
Normal,
121+
Silent,
122+
LocalTest,
123+
GlobalTest,
124+
SilentTest
125+
};
126+
127+
enum IrqType {
128+
RxIrq = 0,
129+
TxIrq,
130+
EwIrq,
131+
DoIrq,
132+
WuIrq,
133+
EpIrq,
134+
AlIrq,
135+
BeIrq,
136+
IdIrq,
137+
138+
IrqCnt
139+
};
140+
141+
} // namespace can
142+
143+
#ifdef FEATURE_EXPERIMENTAL_API
144+
145+
// Pure virtual interface for CAN
146+
struct CAN {
147+
148+
using Mode = ::mbed::interface::can::Mode;
149+
using IrqType = ::mbed::interface::can::IrqType;
150+
151+
virtual ~CAN() = default;
152+
virtual int frequency(int hz) = 0;
153+
virtual int write(CANMessage msg) = 0;
154+
virtual int read(CANMessage &msg, int handle = 0) = 0;
155+
virtual void reset() = 0;
156+
virtual void monitor(bool silent) = 0;
157+
virtual int mode(Mode mode) = 0;
158+
virtual int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0) = 0;
159+
virtual unsigned char rderror() = 0;
160+
virtual unsigned char tderror() = 0;
161+
virtual void attach(Callback<void()> func, IrqType type = IrqType::RxIrq) = 0;
162+
};
163+
164+
#else
165+
using CAN = ::mbed::CAN;
166+
#endif
167+
168+
} // namespace interface
169+
} // namespace mbed
170+
171+
#endif /* MBED_INTERFACE_CAN_H_ */

drivers/source/CAN.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ CAN::~CAN()
5555
// No lock needed in destructor
5656

5757
// Detaching interrupts releases the sleep lock if it was locked
58-
for (int irq = 0; irq < IrqCnt; irq++) {
58+
for (int irq = 0; irq < IrqType::IrqCnt; irq++) {
5959
attach(nullptr, (IrqType)irq);
6060
}
6161
can_irq_free(&_can);

0 commit comments

Comments
 (0)