1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #ifndef CAN_CORE_H
10 #define CAN_CORE_H
11
12 #include "can_if.h"
13 #include "can_manager.h"
14 #include "can_msg.h"
15 #include "can_service.h"
16 #include "hdf_base.h"
17 #include "hdf_dlist.h"
18 #include "hdf_sref.h"
19 #include "osal_mutex.h"
20 #include "platform_core.h"
21
22 #define CAN_THREAD_RUNNING (0x1)
23 #define CAN_THREAD_PENDING (0x1 << 1)
24 #define CAN_THREAD_STOPPED (0x1 << 2)
25 #define THREAD_EXIT_TIMEOUT 2000 // ms
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif /* __cplusplus */
30
31 struct CanCntlr;
32 struct CanRxBox;
33
34 struct CanCntlrMethod {
35 int32_t (*open)(struct CanCntlr *cntlr);
36 int32_t (*close)(struct CanCntlr *cntlr);
37 int32_t (*lock)(struct CanCntlr *cntlr);
38 int32_t (*unlock)(struct CanCntlr *cntlr);
39 int32_t (*sendMsg)(struct CanCntlr *cntlr, const struct CanMsg *msg);
40 int32_t (*setCfg)(struct CanCntlr *cntlr, const struct CanConfig *cfg);
41 int32_t (*getCfg)(struct CanCntlr *cntlr, struct CanConfig *cfg);
42 int32_t (*getState)(struct CanCntlr *cntlr);
43 };
44
45 struct CanCntlr {
46 int32_t number; // bus number
47 int32_t speed; // bit rate
48 int32_t state; // bus status
49 int32_t mode; // work mode
50 size_t msgPoolSize; // size of msg pool
51 /*
52 * the members below are used by framework
53 * don't init or modify them
54 */
55 struct CanCntlrMethod *ops;
56 struct PlatformDevice device;
57 struct OsalMutex lock;
58 struct DListHead filters;
59 struct DListHead rxBoxList;
60 struct OsalMutex rboxListLock;
61 struct CanMsgPool *msgPool;
62 struct OsalThread thread; // Irq thread
63 const struct CanMsg *irqMsg;
64 struct OsalSem sem;
65 uint8_t threadStatus;
66 };
67
68 enum CanErrState {
69 CAN_ERR_ACTIVE, // error active CAN_ERR_PASSIVE, // error passive
70 CAN_ERR_BUS_OFF, // error bus off
71 };
72
73 struct CanTiming {
74 uint32_t brp; // prescaler
75 uint32_t sjw; // sync jump width
76 uint32_t seg1; // phase segment 1
77 uint32_t seg2; // phase segment 2
78 };
79
80 // HDF dev relationship manage
CanCntlrSetHdfDev(struct CanCntlr * cntlr,struct HdfDeviceObject * device)81 static inline int32_t CanCntlrSetHdfDev(struct CanCntlr *cntlr, struct HdfDeviceObject *device)
82 {
83 return PlatformDeviceSetHdfDev(&cntlr->device, device);
84 }
85
CanCntlrFromHdfDev(const struct HdfDeviceObject * device)86 static inline struct CanCntlr *CanCntlrFromHdfDev(const struct HdfDeviceObject *device)
87 {
88 struct PlatformDevice *pdevice = PlatformDeviceFromHdfDev(device);
89 return (pdevice == NULL) ? NULL : CONTAINER_OF(pdevice, struct CanCntlr, device);
90 }
91
92 // CAN BUS operations
93 int32_t CanCntlrWriteMsg(struct CanCntlr *cntlr, const struct CanMsg *msg);
94
95 int32_t CanCntlrSetCfg(struct CanCntlr *cntlr, const struct CanConfig *cfg);
96
97 int32_t CanCntlrGetCfg(struct CanCntlr *cntlr, struct CanConfig *cfg);
98
99 int32_t CanCntlrGetState(struct CanCntlr *cntlr);
100
101 int32_t CanCntlrOnNewMsg(struct CanCntlr *cntlr, const struct CanMsg *msg);
102
103 int32_t CanCntlrOnNewMsgIrqSafe(struct CanCntlr *cntlr, const struct CanMsg *msg);
104
105 int32_t CanCntlrAddRxBox(struct CanCntlr *cntlr, struct CanRxBox *rxBox);
106
107 int32_t CanCntlrDelRxBox(struct CanCntlr *cntlr, struct CanRxBox *rxBox);
108
109 #ifdef __cplusplus
110 }
111 #endif /* __cplusplus */
112
113 #endif
114