]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/rpp/can.c
Make rpp_can_write() not to fail when previous TX request is pending
[pes-rpp/rpp-lib.git] / rpp / src / rpp / can.c
1 /* Copyright (C) 2013-2014 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Carlos Jenkins <carlos@jenkins.co.cr>
5  *     - Karolína Burešová <karry@karryanna.cz>
6  *
7  * This document contains proprietary information belonging to Czech
8  * Technical University in Prague. Passing on and copying of this
9  * document, and communication of its contents is not permitted
10  * without prior written authorization.
11  *
12  * File : can.c
13  * Abstract:
14  *     CAN Bus Communication RPP API implementation file.
15  *
16  * References:
17  *     can.h
18  *     RPP API documentation.
19  */
20
21
22 #include "rpp/rpp.h"
23 #include <math.h>
24 #include "sys/ti_drv_dmm.h"
25
26 static const struct rpp_can_config *can_config = NULL;
27
28 typedef volatile struct CANBase
29 {
30     uint32_t      CTL;          /**< 0x0000: Control Register                       */
31     uint32_t      ES;           /**< 0x0004: Error and Status Register              */
32     uint32_t      EERC;         /**< 0x0008: Error Counter Register                 */
33     uint32_t      BTR;          /**< 0x000C: Bit Timing Register                    */
34     uint32_t      INT;          /**< 0x0010: Interrupt Register                     */
35     uint32_t      TEST;         /**< 0x0014: Test Register                          */
36     uint32_t      : 32U;        /**< 0x0018: Reserved                               */
37     uint32_t      PERR;         /**< 0x001C: Parity/SECDED Error Code Register      */
38     uint32_t      REL;          /**< 0x0020: Core Release Register                  */
39     uint32_t      ECCDIAG;      /**< 0x0024: ECC Diagnostic Register                */
40     uint32_t      ECCDIADSTAT;  /**< 0x0028: ECC Diagnostic Status Register         */
41     uint32_t      : 32U;        /**< 0x002C: Reserved                               */
42     uint32_t      : 32U;        /**< 0x0030: Reserved                               */
43     uint32_t      : 32U;        /**< 0x0034: Reserved                               */
44     uint32_t      : 32U;        /**< 0x0038: Reserved                               */
45     uint32_t      : 32U;        /**< 0x003C: Reserved                               */
46     uint32_t      : 32U;        /**< 0x0040: Reserved                               */
47     uint32_t      : 32U;        /**< 0x0044: Reserved                               */
48     uint32_t      : 32U;        /**< 0x0048: Reserved                               */
49     uint32_t      : 32U;        /**< 0x004C: Reserved                               */
50     uint32_t      : 32U;        /**< 0x0050: Reserved                               */
51     uint32_t      : 32U;        /**< 0x0054: Reserved                               */
52     uint32_t      : 32U;        /**< 0x0058: Reserved                               */
53     uint32_t      : 32U;        /**< 0x005C: Reserved                               */
54     uint32_t      : 32U;        /**< 0x0060: Reserved                               */
55     uint32_t      : 32U;        /**< 0x0064: Reserved                               */
56     uint32_t      : 32U;        /**< 0x0068: Reserved                               */
57     uint32_t      : 32U;        /**< 0x006C: Reserved                               */
58     uint32_t      : 32U;        /**< 0x0070: Reserved                               */
59     uint32_t      : 32U;        /**< 0x0074: Reserved                               */
60     uint32_t      : 32U;        /**< 0x0078: Reserved                               */
61     uint32_t      : 32U;        /**< 0x007C: Reserved                               */
62     uint32_t      ABOTR;        /**< 0x0080: Auto Bus On Time Register              */
63     uint32_t      TXRQX;        /**< 0x0084: Transmission Request X Register        */
64     uint32_t      TXRQx[4U];    /**< 0x0088-0x0094: Transmission Request Registers  */
65     uint32_t      NWDATX;       /**< 0x0098: New Data X Register                    */
66     uint32_t      NWDATx[4U];   /**< 0x009C-0x00A8: New Data Registers              */
67     uint32_t      INTPNDX;      /**< 0x00AC: Interrupt Pending X Register           */
68     uint32_t      INTPNDx[4U];  /**< 0x00B0-0x00BC: Interrupt Pending Registers     */
69     uint32_t      MSGVALX;      /**< 0x00C0: Message Valid X Register               */
70     uint32_t      MSGVALx[4U];  /**< 0x00C4-0x00D0: Message Valid Registers         */
71     uint32_t      : 32U;        /**< 0x00D4: Reserved                               */
72     uint32_t      INTMUXx[4U];  /**< 0x00D8-0x00E4: Interrupt Multiplexer Registers */
73     uint32_t      : 32U;        /**< 0x00E8: Reserved                               */
74     uint32_t      : 32U;        /**< 0x00EC: Reserved                               */
75     uint32_t      : 32U;        /**< 0x00F0: Reserved                               */
76     uint32_t      : 32U;        /**< 0x00F4: Reserved                               */
77     uint32_t      : 32U;        /**< 0x00F8: Reserved                               */
78     uint32_t      : 32U;        /**< 0x00FC: Reserved                               */
79 #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
80     uint8_t IF1NO;              /**< 0x0100: IF1 Command Register, Msg Number       */
81     uint8_t IF1STAT;            /**< 0x0100: IF1 Command Register, Status           */
82     uint8_t IF1CMD;             /**< 0x0100: IF1 Command Register, Command          */
83     uint32_t      : 8U;         /**< 0x0100: IF1 Command Register, Reserved         */
84 #else
85     uint32_t      : 8U;         /**< 0x0100: IF1 Command Register, Reserved         */
86     uint8_t IF1CMD;             /**< 0x0100: IF1 Command Register, Command          */
87     uint8_t IF1STAT;            /**< 0x0100: IF1 Command Register, Status           */
88     uint8_t IF1NO;              /**< 0x0100: IF1 Command Register, Msg Number       */
89 #endif
90     uint32_t      IF1MSK;       /**< 0x0104: IF1 Mask Register                      */
91     uint32_t      IF1ARB;       /**< 0x0108: IF1 Arbitration Register               */
92     uint32_t      IF1MCTL;      /**< 0x010C: IF1 Message Control Register           */
93     uint8_t IF1DATx[8U];        /**< 0x0110-0x0114: IF1 Data A and B Registers      */
94     uint32_t      : 32U;        /**< 0x0118: Reserved                               */
95     uint32_t      : 32U;        /**< 0x011C: Reserved                               */
96 #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
97     uint8_t IF2NO;              /**< 0x0120: IF2 Command Register, Msg No           */
98     uint8_t IF2STAT;            /**< 0x0120: IF2 Command Register, Status           */
99     uint8_t IF2CMD;             /**< 0x0120: IF2 Command Register, Command          */
100     uint32_t      : 8U;         /**< 0x0120: IF2 Command Register, Reserved         */
101 #else
102     uint32_t      : 8U;         /**< 0x0120: IF2 Command Register, Reserved         */
103     uint8_t IF2CMD;             /**< 0x0120: IF2 Command Register, Command          */
104     uint8_t IF2STAT;            /**< 0x0120: IF2 Command Register, Status           */
105     uint8_t IF2NO;              /**< 0x0120: IF2 Command Register, Msg Number       */
106 #endif
107     uint32_t      IF2MSK;       /**< 0x0124: IF2 Mask Register                      */
108     uint32_t      IF2ARB;       /**< 0x0128: IF2 Arbitration Register               */
109     uint32_t      IF2MCTL;      /**< 0x012C: IF2 Message Control Register           */
110     uint8_t IF2DATx[8U];        /**< 0x0130-0x0134: IF2 Data A and B Registers      */
111     uint32_t      : 32U;        /**< 0x0138: Reserved                               */
112     uint32_t      : 32U;        /**< 0x013C: Reserved                               */
113     uint32_t      IF3OBS;       /**< 0x0140: IF3 Observation Register               */
114     uint32_t      IF3MSK;       /**< 0x0144: IF3 Mask Register                      */
115     uint32_t      IF3ARB;       /**< 0x0148: IF3 Arbitration Register               */
116     uint32_t      IF3MCTL;      /**< 0x014C: IF3 Message Control Register           */
117     uint8_t IF3DATx[8U];        /**< 0x0150-0x0154: IF3 Data A and B Registers      */
118     uint32_t      : 32U;        /**< 0x0158: Reserved                               */
119     uint32_t      : 32U;        /**< 0x015C: Reserved                               */
120     uint32_t      IF3UEy[4U];   /**< 0x0160-0x016C: IF3 Update Enable Registers     */
121     uint32_t      : 32U;        /**< 0x0170: Reserved                               */
122     uint32_t      : 32U;        /**< 0x0174: Reserved                               */
123     uint32_t      : 32U;        /**< 0x0178: Reserved                               */
124     uint32_t      : 32U;        /**< 0x017C: Reserved                               */
125     uint32_t      : 32U;        /**< 0x0180: Reserved                               */
126     uint32_t      : 32U;        /**< 0x0184: Reserved                               */
127     uint32_t      : 32U;        /**< 0x0188: Reserved                               */
128     uint32_t      : 32U;        /**< 0x018C: Reserved                               */
129     uint32_t      : 32U;        /**< 0x0190: Reserved                               */
130     uint32_t      : 32U;        /**< 0x0194: Reserved                               */
131     uint32_t      : 32U;        /**< 0x0198: Reserved                               */
132     uint32_t      : 32U;        /**< 0x019C: Reserved                               */
133     uint32_t      : 32U;        /**< 0x01A0: Reserved                               */
134     uint32_t      : 32U;        /**< 0x01A4: Reserved                               */
135     uint32_t      : 32U;        /**< 0x01A8: Reserved                               */
136     uint32_t      : 32U;        /**< 0x01AC: Reserved                               */
137     uint32_t      : 32U;        /**< 0x01B0: Reserved                               */
138     uint32_t      : 32U;        /**< 0x01B4: Reserved                               */
139     uint32_t      : 32U;        /**< 0x01B8: Reserved                               */
140     uint32_t      : 32U;        /**< 0x01BC: Reserved                               */
141     uint32_t      : 32U;        /**< 0x01C0: Reserved                               */
142     uint32_t      : 32U;        /**< 0x01C4: Reserved                               */
143     uint32_t      : 32U;        /**< 0x01C8: Reserved                               */
144     uint32_t      : 32U;        /**< 0x01CC: Reserved                               */
145     uint32_t      : 32U;        /**< 0x01D0: Reserved                               */
146     uint32_t      : 32U;        /**< 0x01D4: Reserved                               */
147     uint32_t      : 32U;        /**< 0x01D8: Reserved                               */
148     uint32_t      : 32U;        /**< 0x01DC: Reserved                               */
149     uint32_t      TIOC;         /**< 0x01E0: TX IO Control Register                 */
150     uint32_t      RIOC;         /**< 0x01E4: RX IO Control Register                 */
151 } canBASE_t;
152
153 #define canREG1 ((canBASE_t *) 0xFFF7DC00U)
154 #define canREG2 ((canBASE_t *) 0xFFF7DE00U)
155 #define canREG3 ((canBASE_t *) 0xFFF7E000U)
156
157 #ifndef __little_endian__
158     static const uint32_t s_can_byte_order[] = {3, 2, 1, 0, 7, 6, 5, 4};
159 #endif
160
161 static canBASE_t *can_base[3] = { canREG1, canREG2, canREG3 };
162
163 static inline canBASE_t * map_controller(uint8_t controller)
164 {
165         if (controller < 1 || controller > 3)
166                 return NULL;
167         return can_base[controller - 1];
168 }
169
170
171 static int8_t init_tx_box(struct rpp_can_tx_config cfg)
172 {
173     canBASE_t *controller;
174
175     if (!(controller = map_controller(cfg.controller)))
176         return FAILURE;
177
178     // Wait until IF1 is ready to use
179     while (controller->IF1STAT & (1U << 7));
180
181     /**
182     * 31 Set whether use of std/ext ID should have effect on acceptance filtering
183     */
184     switch (cfg.type) {
185                 case RPP_CAN_STANDARD:
186                         controller->IF1MSK = 0U << 31;
187                         break;
188                 case RPP_CAN_MIXED:
189                         controller->IF1MSK = 1U << 31;
190                         break;
191                 case RPP_CAN_EXTENDED:
192                         controller->IF1MSK = 1U << 31;
193                         break;
194     }
195
196     /**
197     * 31 Message object is valid
198     * 30 Set whether to use extented identifier
199     * 29 Set direction as transmit
200     */
201     controller->IF1ARB = (1U << 31)
202                           | ((cfg.type == RPP_CAN_STANDARD ? 0 : 1) << 30)
203                           | (1 << 29);
204
205     /**
206     *  7 End of buffer
207     * 4-1 Data length code
208     */
209     controller->IF1MCTL = (1 << 7)
210                            | 8;
211
212     /**
213     * Note that IF1CMD does not refer to whole CMD register
214     * (it refers to bits 23-16 of that register)
215     *  7 Transfer from IF to message object
216     *  5 Transfer arbitration bits
217     *  4 Transfer control bits
218     */
219     controller->IF1CMD = (1U << 7)
220                           | (1 << 5)
221                           | (1 << 4);
222
223     // Write MSG object number and enable transfer
224     controller->IF1NO = cfg.msg_obj;
225
226     return SUCCESS;
227 }
228
229 static int8_t init_rx_box(struct rpp_can_rx_config cfg)
230 {
231     canBASE_t *controller;
232
233     if (!(controller = map_controller(cfg.controller)))
234         return FAILURE;
235
236     // Wait until IF2 is ready to use
237     while (controller->IF2STAT & (1U << 7));
238
239     /**
240     * 31 Set whether use of std/ext ID should have effect on acceptance filtering
241     * 28-1 Set mask
242     */
243     switch (cfg.type) {
244                 case RPP_CAN_STANDARD:
245                         controller->IF2MSK = (1U << 31) | (cfg.mask << 18);
246                         break;
247                 case RPP_CAN_MIXED:
248                         controller->IF2MSK = (0U << 31) | cfg.mask;
249                         break;
250                 case RPP_CAN_EXTENDED:
251                         controller->IF2MSK = (1U << 31) | cfg.mask;
252                         break;
253     }
254
255     /**
256     * 31 Message object is valid
257     * 30 Set whether extended ID should be used
258     * 29 Direction is read
259     * 28-18 / 28-1 Object ID
260     */
261     controller->IF2ARB = (1U << 31)     // MsgVal
262                           | ((cfg.type == RPP_CAN_STANDARD ? 0 : 1) << 30)
263                           | (0 << 29)   // Dir
264                           | cfg.id << (cfg.type == RPP_CAN_STANDARD ? 18 : 0);
265     /**
266     * 12 Use mask for filtering
267     *  7 End of buffer
268     * 4-1 Data length code
269     */
270     controller->IF2MCTL = (1 << 12)
271                            | (1 << 7)
272                            | 8;
273
274     /**
275     * Note that IF2CMD does not refer to whole CMD register
276     * (it refers to bits 23-16 of that register)
277     *  7 Transfer from IF to message object
278     *  6 Transfer mask bits
279     *  5 Transfer arbitration bits
280     *  4 Transfer control bits
281     */
282     controller->IF2CMD = (1 << 7)
283                           | (1 << 6)
284                           | (1 << 5)
285                           | (1 << 4);
286
287     // Write MSG object number and enable transfer
288     controller->IF2NO = cfg.msg_obj;
289
290     return SUCCESS;
291 }
292
293
294
295 static int8_t can_reset(canBASE_t *controller)
296 {
297     /**
298     * 6 Request write access to config registers
299     * 0 Enter initialization mode
300     */
301     controller->CTL = 0
302                        | (1 << 6)
303                        | (1 << 0);
304
305     controller->ES;
306     controller->ABOTR = 0;
307
308     controller->TIOC = (0 << 0);
309     controller->RIOC = (0 << 0);
310
311     return SUCCESS;
312 }
313
314 static int8_t can_set_timing(canBASE_t *controller, const struct rpp_can_timing_cfg cfg) {
315         controller->BTR = (((cfg.brp-1) >> 6) << 16)
316                                 | ((cfg.phase_seg2-1) << 12)
317                                 | (((cfg.phase_seg1+cfg.prop_seg)-1) << 8)
318                                 | ((cfg.sjw-1) << 6)
319                                 | ((cfg.brp-1) & 63);
320         return SUCCESS;
321 }
322
323 /* This code has been taken from can-calc-bit-timing.c */
324 /* can-calc-bit-timing.c: Calculate CAN bit timing parameters
325  *
326  * Derived from:
327  *   can_baud.c - CAN baudrate calculation
328  *   Code based on LinCAN sources and H8S2638 project
329  *   Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
330  *   Copyright 2005      Stanislav Marek
331  *   email:pisa@cmp.felk.cvut.cz
332  *
333  *   With permission from Pavel Pisa to distribute the code and
334  *   software under other license than GPL.
335  */
336 static int can_update_spt(int phase_seg2_min, int phase_seg2_max, int prop_seg_max, int phase_seg1_max,
337                           int sampl_pt, int tseg, int *tseg1, int *tseg2)
338 {
339         *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
340         if (*tseg2 < phase_seg2_min)
341                 *tseg2 = phase_seg2_min;
342         if (*tseg2 > phase_seg2_max)
343                 *tseg2 = phase_seg2_max;
344         *tseg1 = tseg - *tseg2;
345         if (*tseg1 > prop_seg_max + phase_seg1_max) {
346                 *tseg1 = prop_seg_max + phase_seg1_max;
347                 *tseg2 = tseg - *tseg1;
348         }
349         return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
350 }
351
352 /* This code has been taken from can-calc-bit-timing.c */
353 /* can-calc-bit-timing.c: Calculate CAN bit timing parameters
354  *
355  * Derived from:
356  *   can_baud.c - CAN baudrate calculation
357  *   Code based on LinCAN sources and H8S2638 project
358  *   Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
359  *   Copyright 2005      Stanislav Marek
360  *   email:pisa@cmp.felk.cvut.cz
361  *
362  *   With permission from Pavel Pisa to distribute the code and
363  *   software under other license than GPL.
364  */
365 static int8_t can_calculate_timing(const struct rpp_can_ctrl_config cfg, struct rpp_can_timing_cfg *timing) {
366         static const int prop_seg_min = 1;
367         static const int prop_seg_max = 8;
368         static const int phase_seg1_min = 1;
369         static const int phase_seg1_max = 8;
370         static const int phase_seg2_min = 1;
371         static const int phase_seg2_max = 8;
372         static const int brp_min = 1;
373         static const int brp_max = 64;
374         static const int brp_inc = 1;
375
376         if (timing == NULL) {
377                 return FAILURE;
378         }
379
380         int sampl_pt;
381         long best_error = 1000000000, error;
382         int best_tseg = 0, best_brp = 0, brp = 0;
383         int spt_error = 1000, spt = 0;
384         long rate = 0;
385         int tseg = 0, tseg1 = 0, tseg2 = 0;
386         uint64_t v64;
387
388         /* Use CIA recommended sample points */
389         if (cfg.baudrate > 800000) {
390                 sampl_pt = 750;
391         }
392         else if (cfg.baudrate > 500000) {
393                 sampl_pt = 800;
394         }
395         else {
396                 sampl_pt = 875;
397         }
398
399         /* tseg even = round down, odd = round up */
400         for (tseg = (prop_seg_max + phase_seg1_max + phase_seg2_max) * 2 + 1;
401                  tseg >= (prop_seg_min + phase_seg1_min + phase_seg2_min) * 2;
402                  tseg--) {
403                 /* Compute all posibilities of tseg choices (tseg=tseg1+tseg2) */
404                 brp = cfg.clk / ((1 + tseg / 2) * cfg.baudrate) + tseg % 2;
405                 /* chose brp step which is possible in system */
406                 brp = (brp / brp_inc) * brp_inc;
407                 if ((brp < brp_min) || (brp > brp_max))
408                         continue;
409                 rate = cfg.clk / (brp * (1 + tseg / 2));
410                 error = cfg.baudrate - rate;
411                 /* tseg brp biterror */
412
413                 if (error < 0)
414                         error = -error;
415                 if (error > best_error)
416                         continue;
417                 best_error = error;
418                 if (error == 0) {
419                         spt = can_update_spt(phase_seg2_min, phase_seg2_max, prop_seg_max, phase_seg1_max, sampl_pt, tseg / 2, &tseg1, &tseg2);
420                         error = sampl_pt - spt;
421                         if (error < 0)
422                                 error = -error;
423                         if (error > spt_error)
424                                 continue;
425                         spt_error = error;
426                 }
427                 best_tseg = tseg / 2;
428                 best_brp = brp;
429                 if (error == 0)
430                         break;
431         }
432
433         if (best_error && (cfg.baudrate / best_error < 10))
434                 return -1;
435
436         tseg2 = best_tseg + 1 - (sampl_pt * (best_tseg + 1)) / 1000;
437         spt = can_update_spt(phase_seg2_min, phase_seg2_max, prop_seg_max, phase_seg1_max, sampl_pt, best_tseg, &tseg1, &tseg2);
438
439         if (tseg2 > tseg1) {
440                 /* sample point < 50% */
441                 timing->phase_seg1 = tseg1 / 2;
442         } else {
443                 /* keep phase_seg{1,2} equal around the sample point */
444                 timing->phase_seg1 = tseg2;
445         }
446         timing->prop_seg = tseg1 - timing->phase_seg1;
447         /* Check prop_seg range if necessary */
448         if (prop_seg_min || prop_seg_max) {
449                 if (timing->prop_seg < prop_seg_min)
450                         timing->prop_seg = prop_seg_min;
451                 else if (timing->prop_seg > prop_seg_max)
452                         timing->prop_seg = prop_seg_max;
453                 timing->phase_seg1 = tseg1 - timing->prop_seg;
454         }
455         timing->phase_seg2 = tseg2;
456         timing->sjw = 1;
457         timing->brp = best_brp;
458         timing->error = best_error;
459         timing->sampl_pt = spt;
460         v64 = (uint64_t)timing->brp * 1000000000UL;
461         v64 /= cfg.clk;
462         timing->tq = (int)v64;
463
464         return SUCCESS;
465 }
466
467 static int8_t can_configure(canBASE_t *controller, const struct rpp_can_ctrl_config cfg)
468 {
469         if (cfg.timing_calc_method == RPP_CAN_TIMING_CALC_AUTO) {
470                 struct rpp_can_timing_cfg timing_cfg;
471                 if (can_calculate_timing(cfg, &timing_cfg) == SUCCESS) {
472                         return can_set_timing(controller, timing_cfg);
473                 }
474                 else {
475                         return FAILURE;
476                 }
477         }
478         else if (cfg.timing_calc_method == RPP_CAN_TIMING_CALC_MANUAL && cfg.timing_config != NULL) {
479                 return can_set_timing(controller, *cfg.timing_config);
480         }
481         else {
482                 return FAILURE;
483         }
484 }
485
486 static inline void can_leave_init(canBASE_t *controller)
487 {
488     controller->CTL &= ~( (1 << 6) | (1 << 0) );
489
490 }
491
492 static int8_t reset_box(canBASE_t *controller, uint32_t msg_obj)
493 {
494     // Wait until IF1 is ready
495     while (controller->IF1STAT & (1U << 7));
496
497     controller->IF1MSK = 0;
498     controller->IF1ARB = 0;
499     controller->IF1MCTL = (1 << 7) | 8;
500     controller->IF1CMD = (1 << 7)
501                           | (1 << 6)
502                           | (1 << 5)
503                           | (1 << 4);
504     controller->IF1NO = msg_obj;
505
506     return SUCCESS;
507 }
508
509 static int8_t reset_boxes(void)
510 {
511     uint32_t i;
512
513     for (i=1; i<=64; i++)
514     {
515         reset_box(canREG1, i);
516     }
517
518     for (i=1; i<=64; i++)
519     {
520         reset_box(canREG2, i);
521     }
522
523     for (i=1; i<=32; i++)
524     {
525         reset_box(canREG3, i);
526     }
527
528     return SUCCESS;
529 }
530
531 int8_t can_setup_IF(canBASE_t *controller)
532 {
533     // Wait until IF1 is ready
534     while (controller->IF1STAT & (1U << 7));
535
536     /**
537     * 7 Transfer from IF to message object
538     * 5 Transfer arbitration bits
539     * 4 Transfer control bits
540     * 2 Set TxRqst bit
541     * 1 Access data bytes 7-4
542     * 0 Access data bytes 3-0
543     */
544     controller->IF1CMD = (1 << 7)
545                           | (1 << 5)
546                           | (1 << 4)
547                           | (1 << 2)
548                           | (1 << 1)
549                           | (1 << 0);
550
551     // Wait until IF2 is ready
552     while (controller->IF2STAT & (1U << 7));
553
554     /**
555     * 7 Transfer from message object to IF
556     * 5 Transfer arbitration bits
557     * 4 Transfer control bits
558     * 2 Clear NewDat bit
559     * 1 Access data bytes 7-4
560     * 0 Access data bytes 3-0
561     */
562     controller->IF2CMD = (0 << 7)
563                           | (1 << 5)
564                           | (1 << 4)
565                           | (1 << 2)
566                           | (1 << 1)
567                           | (1 << 0);
568
569     return SUCCESS;
570 }
571
572 int8_t rpp_can_init(const struct rpp_can_config *config)
573 {
574     uint16_t i;
575 #ifndef FREERTOS_POSIX
576     dmmInit();
577
578     /*
579      * Reset the bus drivers to NORMAL MODE. Refer TJA1041A reference for more details
580      * about the states of the driver.
581      */
582     dmmREG->PC4 = 1<<13; // set CAN_NSTB
583     dmmREG->PC5 = 1<<15; // clr CAN_EN
584     dmmREG->PC5 = 1<<13; // clr CAN_NSTB
585     dmmREG->PC4 = 1<<13; // set CAN_NSTB
586     dmmREG->PC4 = 1<<15; // set CAN_EN
587 #endif
588     can_config = config;
589
590     if (can_reset(canREG1) == FAILURE)
591        return FAILURE;
592     if (can_reset(canREG2) == FAILURE)
593        return FAILURE;
594     if (can_reset(canREG3) == FAILURE)
595        return FAILURE;
596
597     if (reset_boxes() == FAILURE)
598        return FAILURE;
599
600     for (i=0; i<config->num_tx_obj; i++)
601     {
602         if (init_tx_box(config->tx_config[i]) == FAILURE)
603            return FAILURE;
604     }
605
606     for (i=0; i<config->num_rx_obj; i++)
607     {
608         if (init_rx_box(config->rx_config[i]) == FAILURE)
609            return FAILURE;
610     }
611
612     if (can_setup_IF(canREG1) == FAILURE)
613         return FAILURE;
614     if (can_setup_IF(canREG2) == FAILURE)
615         return FAILURE;
616     if (can_setup_IF(canREG3) == FAILURE)
617         return FAILURE;
618
619     if (can_configure(canREG1, config->ctrl[0]) == FAILURE)
620         return FAILURE;
621     if (can_configure(canREG2, config->ctrl[1]) == FAILURE)
622         return FAILURE;
623     if (can_configure(canREG3, config->ctrl[2]) == FAILURE)
624         return FAILURE;
625
626     can_leave_init(canREG1);
627     can_leave_init(canREG2);
628     can_leave_init(canREG3);
629
630     return SUCCESS;
631 }
632
633
634 int8_t rpp_can_write(rpp_can_hw_obj hw_obj, const struct rpp_can_pdu *pdu)
635 {
636     uint8_t i;
637     canBASE_t *controller;
638     struct rpp_can_tx_config *tx_cfg = &can_config->tx_config[hw_obj];
639
640     if (!(controller = map_controller(tx_cfg->controller)))
641     {
642         return -RPP_EINVAL;
643     }
644
645     // Wait until IF1 is ready to use
646     while (controller->IF1STAT & (1U << 7));
647
648     // Reset data length code
649     controller->IF1MCTL &= ~15;
650     controller->IF1MCTL |= pdu->dlc & 0xF;
651
652     /**
653     * 31 Message is valid
654     * 30 Whether std/ext ID should be used
655     * 29 Direction is transmit
656     * 28-18 / 28-0 Message ID
657     */
658     controller->IF1ARB = (1 << 31)
659                           | ((tx_cfg->type == RPP_CAN_STANDARD ? 0 : 1) << 30)
660                           | (1 << 29)
661                           | (pdu->id << (tx_cfg->type == RPP_CAN_STANDARD ? 18 : 0));
662
663     for (i=0; i<pdu->dlc; i++)
664     {
665 #ifdef __little_endian__
666         controller->IF1DATx[i] = pdu->data[i];
667 #else
668         controller->IF1DATx[s_can_byte_order[i]] = pdu->data[i];
669 #endif
670     }
671
672     // Copy TX data into message box
673     controller->IF1NO = tx_cfg->msg_obj;
674
675     return SUCCESS;
676 }
677
678
679 int8_t rpp_can_check_tx_pend(rpp_can_hw_obj hw_obj, bool *tx_pend)
680 {
681     uint32_t reg_index, bit_mask;
682     canBASE_t *controller;
683
684     if (!(controller = map_controller(can_config->tx_config[hw_obj].controller)))
685     {
686         return FAILURE;
687     }
688
689     reg_index = can_config->tx_config[hw_obj].msg_obj >> 5;
690     bit_mask = 1 << ((can_config->tx_config[hw_obj].msg_obj - 1) & 0x1FU);
691
692     *tx_pend = controller->TXRQx[reg_index] & bit_mask;
693
694     return SUCCESS;
695 }
696
697 int8_t rpp_can_read(rpp_can_hw_obj hw_obj, struct rpp_can_pdu *pdu)
698 {
699     uint32_t reg_index, bit_mask;
700     uint32_t i;
701     canBASE_t *controller;
702
703     if (!(controller = map_controller(can_config->rx_config[hw_obj].controller)))
704     {
705         return -RPP_EINVAL;
706     }
707
708     reg_index = (can_config->rx_config[hw_obj].msg_obj - 1) >> 5;
709     bit_mask = 1 << ((can_config->rx_config[hw_obj].msg_obj - 1) & 0x1FU);
710
711     // FIXME: Check whether to abort if there are no new data
712     if (!(controller->NWDATx[reg_index] & bit_mask))
713     {
714         return -RPP_ENODATA;
715     }
716
717     // Wait until IF2 is ready to use
718     while (controller->IF2STAT & (1U << 7));
719
720     // Copy data into IF2
721     controller->IF2NO = can_config->rx_config[hw_obj].msg_obj;
722
723     // Wait until IF2 is ready to use
724     while (controller->IF2STAT & (1U << 7));
725
726     // Get length of data received
727     pdu->dlc = controller->IF2MCTL & 0xFU;
728
729     // Get message ID
730     if (controller->IF2ARB & (1 << 30))
731     {
732         pdu->id = (controller->IF2ARB & 0x1FFFFFFF) | CAN_EFF_FLAG;
733     }
734     else
735     {
736         pdu->id = (controller->IF2ARB & (0x7FF << 18)) >> 18;
737     }
738
739     // Copy RX data into pdu
740     for (i=0; i<pdu->dlc; i++)
741     {
742 #ifdef __little_endian__
743         pdu->data[i] = controller->IF2DATx[i];
744 #else
745         pdu->data[i] = controller->IF2DATx[s_can_byte_order[i]];
746 #endif
747     }
748
749     return SUCCESS;
750 }
751
752 int8_t rpp_can_check_rx_ind(rpp_can_hw_obj hw_obj, bool *rx_ind)
753 {
754     uint32_t reg_index, bit_mask;
755     canBASE_t *controller;
756
757     if (!(controller = map_controller(can_config->rx_config[hw_obj].controller)))
758     {
759         return FAILURE;
760     }
761
762     reg_index = (can_config->rx_config[hw_obj].msg_obj - 1) >> 5;
763     bit_mask = 1 << ((can_config->rx_config[hw_obj].msg_obj - 1) & 0x1FU);
764
765     *rx_ind = controller->NWDATx[reg_index] & bit_mask;
766
767     return SUCCESS;
768 }