forked from ShunzDai/J1939
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathj1939_port.c
183 lines (172 loc) · 5.52 KB
/
j1939_port.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/**
* Copyright 2022 ShunzDai
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "j1939_port.h"
#include "src/common/J1939_queue.h"
#include "src/message/j1939_message.h"
#include "src/memory/j1939_memory.h"
/**
* @brief CAN port initialization
* @param Port CAN port printer
* @retval J1939 status
*/
J1939_Status_t J1939_PortInit(J1939_Port_t *Port){
#if __J1939_Port(SUSPEND)
return J1939_OK;
#elif __J1939_Port(VIRTUAL)
*Port = J1939_VirtualNodeCreate();
return J1939_OK;
#elif __J1939_Port(STM32)
CAN_FilterTypeDef Filter = {0};
Filter.FilterActivation = CAN_FILTER_ENABLE;
Filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
Filter.FilterBank = 0;
/* Config filter mode(CAN_FILTERMODE_IDMASK or CAN_FILTERMODE_IDLIST) */
Filter.FilterMode = CAN_FILTERMODE_IDMASK;
/* Config filter scale */
Filter.FilterScale = CAN_FILTERSCALE_32BIT;
Filter.FilterIdHigh = 0x0000;
Filter.FilterIdLow = 0x0000;
Filter.FilterMaskIdHigh = 0x0000;
Filter.FilterMaskIdLow = 0x0000;
if (HAL_CAN_ConfigFilter(Port, &Filter) == HAL_OK)
return (J1939_Status_t)HAL_CAN_Start(Port);
else
return J1939_ERROR;
#else /* __J1939_Port() */
#error "Incompatible port"
#endif /* __J1939_Port() */
}
/**
* @brief CAN port de-initialization
* @param Port CAN port printer
* @retval J1939 status
*/
J1939_Status_t J1939_PortDeInit(J1939_Port_t *Port){
#if __J1939_Port(SUSPEND)
return J1939_OK;
#elif __J1939_Port(VIRTUAL)
return J1939_VirtualNodeDelete(Port);
#elif __J1939_Port(STM32)
return (J1939_Status_t)HAL_CAN_Stop(Port);
#else /* __J1939_Port() */
#error "Incompatible port"
#endif /* __J1939_Port() */
}
/**
* @brief Get system tick
* @param void
* @retval System tick
*/
uint64_t J1939_PortGetTick(void){
#if __J1939_Port(SUSPEND)
return 0;
#elif __J1939_Port(VIRTUAL)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t)(ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
#elif __J1939_Port(STM32)
return (uint64_t)HAL_GetTick();
#else /* __J1939_Port() */
#error "Incompatible port"
#endif /* __J1939_Port() */
}
/**
* @brief Check transmit mailbox free level
* @param Port CAN port printer
* @retval transmit mailbox free level
*/
uint32_t J1939_PortGetTxMailboxesFreeLevel(J1939_Port_t *Port){
#if __J1939_Port(SUSPEND)
return 1;
#elif __J1939_Port(VIRTUAL)
return J1939_VirtualGetTxMailboxesFreeLevel(*Port);
#elif __J1939_Port(STM32)
return HAL_CAN_GetTxMailboxesFreeLevel(Port);
#else /* __J1939_Port() */
#error "Incompatible port"
#endif /* __J1939_Port() */
}
/**
* @brief Check receive mailbox fill level
* @param Port CAN port printer
* @retval receive mailbox fill level
*/
uint32_t J1939_PortGetRxFifoFillLevel(J1939_Port_t *Port){
#if __J1939_Port(SUSPEND)
return 0;
#elif __J1939_Port(VIRTUAL)
return J1939_VirtualGetRxFifoFillLevel(*Port);
#elif __J1939_Port(STM32)
return HAL_CAN_GetRxFifoFillLevel(Port, CAN_RX_FIFO0);
#else /* __J1939_Port() */
#error "Incompatible port"
#endif /* __J1939_Port() */
}
/**
* @brief Add message into transmit mailbox
* @param Port CAN port printer
* @param Msg J1939 message
* @retval J1939 status
*/
J1939_Status_t J1939_PortAddTxMessage(J1939_Port_t *Port, J1939_Message_t Msg){
#if __J1939_Port(SUSPEND)
return J1939_OK;
#elif __J1939_Port(VIRTUAL)
return J1939_VirtualAddTxMessage(*Port, Msg);
#elif __J1939_Port(STM32)
uint32_t Mailbox = 0;
CAN_TxHeaderTypeDef TxHeader;
TxHeader.IDE = CAN_ID_EXT;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.DLC = Msg->Length;
TxHeader.ExtId = Msg->ID;
if (HAL_CAN_AddTxMessage(Port, &TxHeader, Msg->Payload, &Mailbox) == HAL_OK)
return J1939_OK;
return J1939_ERROR;
#else /* __J1939_Port() */
#error "Incompatible port"
#endif /* __J1939_Port() */
}
/**
* @brief Get message from receive mailbox
* @param Port CAN port printer
* @param MsgPtr Message buffer printer
* @retval J1939 status
*/
J1939_Status_t J1939_PortGetRxMessage(J1939_Port_t *Port, J1939_Message_t *MsgPtr){
#if __J1939_Port(SUSPEND)
return J1939_OK;
#elif __J1939_Port(VIRTUAL)
return J1939_VirtualGetRxMessage(*Port, MsgPtr);
#elif __J1939_Port(STM32)
CAN_RxHeaderTypeDef RxHeader;
*MsgPtr = J1939_MessageCreate(0, J1939_SIZE_CAN_BUFFER, NULL);
if (HAL_CAN_GetRxMessage(Port, CAN_FILTER_FIFO0, &RxHeader, (*MsgPtr)->Payload) == HAL_OK){
(*MsgPtr)->ID = RxHeader.ExtId;
(*MsgPtr)->Length = RxHeader.DLC;
return J1939_OK;
}
J1939_MessageDelete(MsgPtr);
return J1939_ERROR;
#else /* __J1939_Port() */
#error "Incompatible port"
#endif /* __J1939_Port() */
}
void J1939_PortAssertError(const char *File, const char *Func, int Line, char *Condition){
printf("Assertion failed: %s\nfile %s, func %s, line %d\n", Condition, File, Func, Line);
while (1);
}