13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
- #include <math.h>
17
- #include <string.h>
18
-
19
16
#include "can_api.h"
17
+
20
18
#include "cmsis.h"
21
19
#include "pinmap.h"
22
20
#include "error.h"
23
21
22
+ #include <math.h>
23
+ #include <string.h>
24
+
25
+ #define CAN_NUM 2
26
+
24
27
/* Acceptance filter mode in AFMR register */
25
28
#define ACCF_OFF 0x01
26
29
#define ACCF_BYPASS 0x02
@@ -60,6 +63,9 @@ struct CANMsg {
60
63
};
61
64
typedef struct CANMsg CANMsg ;
62
65
66
+ static uint32_t can_irq_ids [CAN_NUM ] = {0 };
67
+ static can_irq_handler irq_handler ;
68
+
63
69
static uint32_t can_disable (can_t * obj ) {
64
70
uint32_t sm = obj -> dev -> MOD ;
65
71
obj -> dev -> MOD |= 1 ;
@@ -72,6 +78,101 @@ static inline void can_enable(can_t *obj) {
72
78
}
73
79
}
74
80
81
+ int can_mode (can_t * obj , CanMode mode )
82
+ {
83
+ return 0 ; // not implemented
84
+ }
85
+
86
+ static inline void can_irq (uint32_t icr , uint32_t index ) {
87
+ uint32_t i ;
88
+
89
+ for (i = 0 ; i < 8 ; i ++ )
90
+ {
91
+ if ((can_irq_ids [index ] != 0 ) && (icr & (1 << i )))
92
+ {
93
+ switch (i ) {
94
+ case 0 : irq_handler (can_irq_ids [index ], IRQ_RX ); break ;
95
+ case 1 : irq_handler (can_irq_ids [index ], IRQ_TX ); break ;
96
+ case 2 : irq_handler (can_irq_ids [index ], IRQ_ERROR ); break ;
97
+ case 3 : irq_handler (can_irq_ids [index ], IRQ_OVERRUN ); break ;
98
+ case 4 : irq_handler (can_irq_ids [index ], IRQ_WAKEUP ); break ;
99
+ case 5 : irq_handler (can_irq_ids [index ], IRQ_PASSIVE ); break ;
100
+ case 6 : irq_handler (can_irq_ids [index ], IRQ_ARB ); break ;
101
+ case 7 : irq_handler (can_irq_ids [index ], IRQ_BUS ); break ;
102
+ case 8 : irq_handler (can_irq_ids [index ], IRQ_READY ); break ;
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ // Have to check that the CAN block is active before reading the Interrupt
109
+ // Control Register, or the mbed hangs
110
+ void can_irq_n () {
111
+ uint32_t icr ;
112
+
113
+ if (LPC_SC -> PCONP & (1 << 13 )) {
114
+ icr = LPC_CAN1 -> ICR & 0x1FF ;
115
+ can_irq (icr , 0 );
116
+ }
117
+
118
+ if (LPC_SC -> PCONP & (1 << 14 )) {
119
+ icr = LPC_CAN2 -> ICR & 0x1FF ;
120
+ can_irq (icr , 1 );
121
+ }
122
+ }
123
+
124
+ // Register CAN object's irq handler
125
+ void can_irq_init (can_t * obj , can_irq_handler handler , uint32_t id ) {
126
+ irq_handler = handler ;
127
+ can_irq_ids [obj -> index ] = id ;
128
+ }
129
+
130
+ // Unregister CAN object's irq handler
131
+ void can_irq_free (can_t * obj ) {
132
+ obj -> dev -> IER &= ~(1 );
133
+ can_irq_ids [obj -> index ] = 0 ;
134
+
135
+ if ((can_irq_ids [0 ] == 0 ) && (can_irq_ids [1 ] == 0 )) {
136
+ NVIC_DisableIRQ (CAN_IRQn );
137
+ }
138
+ }
139
+
140
+ // Clear or set a irq
141
+ void can_irq_set (can_t * obj , CanIrqType type , uint32_t enable ) {
142
+ uint32_t ier ;
143
+
144
+ switch (type ) {
145
+ case IRQ_RX : ier = (1 << 0 ); break ;
146
+ case IRQ_TX : ier = (1 << 1 ); break ;
147
+ case IRQ_ERROR : ier = (1 << 2 ); break ;
148
+ case IRQ_OVERRUN : ier = (1 << 3 ); break ;
149
+ case IRQ_WAKEUP : ier = (1 << 4 ); break ;
150
+ case IRQ_PASSIVE : ier = (1 << 5 ); break ;
151
+ case IRQ_ARB : ier = (1 << 6 ); break ;
152
+ case IRQ_BUS : ier = (1 << 7 ); break ;
153
+ case IRQ_READY : ier = (1 << 8 ); break ;
154
+ default : return ;
155
+ }
156
+
157
+ obj -> dev -> MOD |= 1 ;
158
+ if (enable == 0 ) {
159
+ obj -> dev -> IER &= ~ier ;
160
+ }
161
+ else {
162
+ obj -> dev -> IER |= ier ;
163
+ }
164
+ obj -> dev -> MOD &= ~(1 );
165
+
166
+ // Enable NVIC if at least 1 interrupt is active
167
+ if (LPC_CAN1 -> IER | LPC_CAN2 -> IER != 0 ) {
168
+ NVIC_SetVector (CAN_IRQn , (uint32_t ) & can_irq_n );
169
+ NVIC_EnableIRQ (CAN_IRQn );
170
+ }
171
+ else {
172
+ NVIC_DisableIRQ (CAN_IRQn );
173
+ }
174
+ }
175
+
75
176
// This table has the sampling points as close to 75% as possible. The first
76
177
// value is TSEG1, the second TSEG2.
77
178
static const int timing_pts [23 ][2 ] = {
@@ -132,6 +233,7 @@ static unsigned int can_speed(unsigned int sclk, unsigned int pclk, unsigned int
132
233
}
133
234
134
235
return btr ;
236
+
135
237
}
136
238
137
239
void can_init (can_t * obj , PinName rd , PinName td ) {
@@ -141,19 +243,24 @@ void can_init(can_t *obj, PinName rd, PinName td) {
141
243
if ((int )obj -> dev == NC ) {
142
244
error ("CAN pin mapping failed" );
143
245
}
144
-
246
+
145
247
switch ((int )obj -> dev ) {
146
248
case CAN_1 : LPC_SC -> PCONP |= 1 << 13 ; break ;
147
249
case CAN_2 : LPC_SC -> PCONP |= 1 << 14 ; break ;
148
250
}
149
-
251
+
150
252
pinmap_pinout (rd , PinMap_CAN_RD );
151
253
pinmap_pinout (td , PinMap_CAN_TD );
152
254
255
+ switch ((int )obj -> dev ) {
256
+ case CAN_1 : obj -> index = 0 ; break ;
257
+ case CAN_2 : obj -> index = 1 ; break ;
258
+ }
259
+
153
260
can_reset (obj );
154
261
obj -> dev -> IER = 0 ; // Disable Interrupts
155
262
can_frequency (obj , 100000 );
156
-
263
+
157
264
LPC_CANAF -> AFMR = ACCF_BYPASS ; // Bypass Filter
158
265
}
159
266
@@ -166,8 +273,9 @@ void can_free(can_t *obj) {
166
273
167
274
int can_frequency (can_t * obj , int f ) {
168
275
int pclk = PeripheralClock ;
169
- int btr = can_speed (SystemCoreClock , pclk , (unsigned int )f , 1 );
170
276
277
+ int btr = can_speed (SystemCoreClock , pclk , (unsigned int )f , 1 );
278
+
171
279
if (btr > 0 ) {
172
280
uint32_t modmask = can_disable (obj );
173
281
obj -> dev -> BTR = btr ;
@@ -181,16 +289,16 @@ int can_frequency(can_t *obj, int f) {
181
289
int can_write (can_t * obj , CAN_Message msg , int cc ) {
182
290
unsigned int CANStatus ;
183
291
CANMsg m ;
184
-
292
+
185
293
can_enable (obj );
186
-
294
+
187
295
m .id = msg .id ;
188
296
m .dlc = msg .len & 0xF ;
189
297
m .rtr = msg .type ;
190
298
m .type = msg .format ;
191
299
memcpy (m .data , msg .data , msg .len );
192
300
const unsigned int * buf = (const unsigned int * )& m ;
193
-
301
+
194
302
CANStatus = obj -> dev -> SR ;
195
303
if (CANStatus & 0x00000004 ) {
196
304
obj -> dev -> TFI1 = buf [0 ] & 0xC00F0000 ;
@@ -203,7 +311,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
203
311
obj -> dev -> CMR = 0x21 ;
204
312
}
205
313
return 1 ;
206
-
314
+
207
315
} else if (CANStatus & 0x00000400 ) {
208
316
obj -> dev -> TFI2 = buf [0 ] & 0xC00F0000 ;
209
317
obj -> dev -> TID2 = buf [1 ];
@@ -215,7 +323,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
215
323
obj -> dev -> CMR = 0x41 ;
216
324
}
217
325
return 1 ;
218
-
326
+
219
327
} else if (CANStatus & 0x00040000 ) {
220
328
obj -> dev -> TFI3 = buf [0 ] & 0xC00F0000 ;
221
329
obj -> dev -> TID3 = buf [1 ];
@@ -228,31 +336,31 @@ int can_write(can_t *obj, CAN_Message msg, int cc) {
228
336
}
229
337
return 1 ;
230
338
}
231
-
339
+
232
340
return 0 ;
233
341
}
234
342
235
343
int can_read (can_t * obj , CAN_Message * msg ) {
236
344
CANMsg x ;
237
345
unsigned int * i = (unsigned int * )& x ;
238
-
346
+
239
347
can_enable (obj );
240
-
348
+
241
349
if (obj -> dev -> GSR & 0x1 ) {
242
350
* i ++ = obj -> dev -> RFS ; // Frame
243
351
* i ++ = obj -> dev -> RID ; // ID
244
352
* i ++ = obj -> dev -> RDA ; // Data A
245
353
* i ++ = obj -> dev -> RDB ; // Data B
246
354
obj -> dev -> CMR = 0x04 ; // release receive buffer
247
-
355
+
248
356
msg -> id = x .id ;
249
357
msg -> len = x .dlc ;
250
358
msg -> format = (x .type )? CANExtended : CANStandard ;
251
359
msg -> type = (x .rtr )? CANRemote : CANData ;
252
360
memcpy (msg -> data ,x .data ,x .dlc );
253
361
return 1 ;
254
362
}
255
-
363
+
256
364
return 0 ;
257
365
}
258
366
0 commit comments