t

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /* mbed Microcontroller Library
bogdanm 0:9b334a45a8ff 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 0:9b334a45a8ff 3 *
bogdanm 0:9b334a45a8ff 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 0:9b334a45a8ff 5 * you may not use this file except in compliance with the License.
bogdanm 0:9b334a45a8ff 6 * You may obtain a copy of the License at
bogdanm 0:9b334a45a8ff 7 *
bogdanm 0:9b334a45a8ff 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 0:9b334a45a8ff 9 *
bogdanm 0:9b334a45a8ff 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 0:9b334a45a8ff 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 0:9b334a45a8ff 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 0:9b334a45a8ff 13 * See the License for the specific language governing permissions and
bogdanm 0:9b334a45a8ff 14 * limitations under the License.
bogdanm 0:9b334a45a8ff 15 */
bogdanm 0:9b334a45a8ff 16 #include <string.h>
bogdanm 0:9b334a45a8ff 17 #include "mbed_assert.h"
bogdanm 0:9b334a45a8ff 18 #include "can_api.h"
bogdanm 0:9b334a45a8ff 19 #include "RZ_A1_Init.h"
bogdanm 0:9b334a45a8ff 20 #include "cmsis.h"
bogdanm 0:9b334a45a8ff 21 #include "pinmap.h"
bogdanm 0:9b334a45a8ff 22 #include "rscan0_iodefine.h"
bogdanm 0:9b334a45a8ff 23 #include "r_typedefs.h"
bogdanm 0:9b334a45a8ff 24 #include "MBRZA1H.h"
bogdanm 0:9b334a45a8ff 25
bogdanm 0:9b334a45a8ff 26 #define CAN_NUM 5
bogdanm 0:9b334a45a8ff 27 #define CAN_SND_RCV 2
bogdanm 0:9b334a45a8ff 28 #define IRQ_NUM 8
bogdanm 0:9b334a45a8ff 29
bogdanm 0:9b334a45a8ff 30 static void can_rec_irq(uint32_t ch);
bogdanm 0:9b334a45a8ff 31 static void can_trx_irq(uint32_t ch);
bogdanm 0:9b334a45a8ff 32 static void can_err_irq(uint32_t ch, CanIrqType type);
bogdanm 0:9b334a45a8ff 33 static void can0_rec_irq(void);
bogdanm 0:9b334a45a8ff 34 static void can1_rec_irq(void);
bogdanm 0:9b334a45a8ff 35 static void can2_rec_irq(void);
bogdanm 0:9b334a45a8ff 36 static void can3_rec_irq(void);
bogdanm 0:9b334a45a8ff 37 static void can4_rec_irq(void);
bogdanm 0:9b334a45a8ff 38 static void can0_trx_irq(void);
bogdanm 0:9b334a45a8ff 39 static void can1_trx_irq(void);
bogdanm 0:9b334a45a8ff 40 static void can2_trx_irq(void);
bogdanm 0:9b334a45a8ff 41 static void can3_trx_irq(void);
bogdanm 0:9b334a45a8ff 42 static void can4_trx_irq(void);
bogdanm 0:9b334a45a8ff 43 static void can0_err_warning_irq(void);
bogdanm 0:9b334a45a8ff 44 static void can1_err_warning_irq(void);
bogdanm 0:9b334a45a8ff 45 static void can2_err_warning_irq(void);
bogdanm 0:9b334a45a8ff 46 static void can3_err_warning_irq(void);
bogdanm 0:9b334a45a8ff 47 static void can4_err_warning_irq(void);
bogdanm 0:9b334a45a8ff 48 static void can0_overrun_irq(void);
bogdanm 0:9b334a45a8ff 49 static void can1_overrun_irq(void);
bogdanm 0:9b334a45a8ff 50 static void can2_overrun_irq(void);
bogdanm 0:9b334a45a8ff 51 static void can3_overrun_irq(void);
bogdanm 0:9b334a45a8ff 52 static void can4_overrun_irq(void);
bogdanm 0:9b334a45a8ff 53 static void can0_passive_irq(void);
bogdanm 0:9b334a45a8ff 54 static void can1_passive_irq(void);
bogdanm 0:9b334a45a8ff 55 static void can2_passive_irq(void);
bogdanm 0:9b334a45a8ff 56 static void can3_passive_irq(void);
bogdanm 0:9b334a45a8ff 57 static void can4_passive_irq(void);
bogdanm 0:9b334a45a8ff 58 static void can0_arb_lost_irq(void);
bogdanm 0:9b334a45a8ff 59 static void can1_arb_lost_irq(void);
bogdanm 0:9b334a45a8ff 60 static void can2_arb_lost_irq(void);
bogdanm 0:9b334a45a8ff 61 static void can3_arb_lost_irq(void);
bogdanm 0:9b334a45a8ff 62 static void can4_arb_lost_irq(void);
bogdanm 0:9b334a45a8ff 63 static void can0_bus_err_irq(void);
bogdanm 0:9b334a45a8ff 64 static void can1_bus_err_irq(void);
bogdanm 0:9b334a45a8ff 65 static void can2_bus_err_irq(void);
bogdanm 0:9b334a45a8ff 66 static void can3_bus_err_irq(void);
bogdanm 0:9b334a45a8ff 67 static void can4_bus_err_irq(void);
bogdanm 0:9b334a45a8ff 68 static void can_reset_reg(can_t *obj);
bogdanm 0:9b334a45a8ff 69 static void can_reset_recv_rule(can_t *obj);
bogdanm 0:9b334a45a8ff 70 static void can_reset_buffer(can_t *obj);
bogdanm 0:9b334a45a8ff 71 static void can_reconfigure_channel(void);
bogdanm 0:9b334a45a8ff 72 static void can_set_frequency(can_t *obj, int f);
bogdanm 0:9b334a45a8ff 73 static void can_set_global_mode(int mode);
bogdanm 0:9b334a45a8ff 74 static void can_set_channel_mode(uint32_t ch, int mode);
bogdanm 0:9b334a45a8ff 75
bogdanm 0:9b334a45a8ff 76 typedef enum {
bogdanm 0:9b334a45a8ff 77 CAN_SEND = 0,
bogdanm 0:9b334a45a8ff 78 CAN_RECV
bogdanm 0:9b334a45a8ff 79 } CANfunc;
bogdanm 0:9b334a45a8ff 80
bogdanm 0:9b334a45a8ff 81 typedef enum {
bogdanm 0:9b334a45a8ff 82 GL_OPE = 0,
bogdanm 0:9b334a45a8ff 83 GL_RESET,
bogdanm 0:9b334a45a8ff 84 GL_TEST
bogdanm 0:9b334a45a8ff 85 } Globalmode;
bogdanm 0:9b334a45a8ff 86
bogdanm 0:9b334a45a8ff 87 typedef enum {
bogdanm 0:9b334a45a8ff 88 CH_COMM = 0,
bogdanm 0:9b334a45a8ff 89 CH_RESET,
bogdanm 0:9b334a45a8ff 90 CH_HOLD
bogdanm 0:9b334a45a8ff 91 } Channelmode;
bogdanm 0:9b334a45a8ff 92
bogdanm 0:9b334a45a8ff 93 typedef struct {
bogdanm 0:9b334a45a8ff 94 IRQn_Type int_num; /* Interrupt number */
bogdanm 0:9b334a45a8ff 95 IRQHandler handler; /* Interrupt handler */
bogdanm 0:9b334a45a8ff 96 } can_info_int_t;
bogdanm 0:9b334a45a8ff 97
bogdanm 0:9b334a45a8ff 98 static can_irq_handler irq_handler;
bogdanm 0:9b334a45a8ff 99 static uint32_t can_irq_id[CAN_NUM];
bogdanm 0:9b334a45a8ff 100 static int can_initialized[CAN_NUM] = {0};
bogdanm 0:9b334a45a8ff 101
bogdanm 0:9b334a45a8ff 102 static const PinMap PinMap_CAN_RD[] = {
bogdanm 0:9b334a45a8ff 103 {P7_8 , CAN_0, 4},
bogdanm 0:9b334a45a8ff 104 {P9_1 , CAN_0, 3},
bogdanm 0:9b334a45a8ff 105 {P1_4 , CAN_1, 3},
bogdanm 0:9b334a45a8ff 106 {P5_9 , CAN_1, 5},
bogdanm 0:9b334a45a8ff 107 {P7_11 , CAN_1, 4},
bogdanm 0:9b334a45a8ff 108 {P11_12, CAN_1, 1},
bogdanm 0:9b334a45a8ff 109 {P4_9 , CAN_2, 6},
bogdanm 0:9b334a45a8ff 110 {P6_4 , CAN_2, 3},
bogdanm 0:9b334a45a8ff 111 {P7_2 , CAN_2, 5},
bogdanm 0:9b334a45a8ff 112 {P2_12 , CAN_3, 5},
bogdanm 0:9b334a45a8ff 113 {P4_2 , CAN_3, 4},
bogdanm 0:9b334a45a8ff 114 {P1_5 , CAN_4, 3},
bogdanm 0:9b334a45a8ff 115 {P2_14 , CAN_4, 5},
bogdanm 0:9b334a45a8ff 116 {NC , NC , 0}
bogdanm 0:9b334a45a8ff 117 };
bogdanm 0:9b334a45a8ff 118
bogdanm 0:9b334a45a8ff 119 static const PinMap PinMap_CAN_TD[] = {
bogdanm 0:9b334a45a8ff 120 {P7_9 , CAN_0, 4},
bogdanm 0:9b334a45a8ff 121 {P9_0 , CAN_0, 3},
bogdanm 0:9b334a45a8ff 122 {P5_10 , CAN_1, 5},
bogdanm 0:9b334a45a8ff 123 {P7_10 , CAN_1, 4},
bogdanm 0:9b334a45a8ff 124 {P11_13, CAN_1, 1},
bogdanm 0:9b334a45a8ff 125 {P4_8 , CAN_2, 6},
bogdanm 0:9b334a45a8ff 126 {P6_5 , CAN_2, 3},
bogdanm 0:9b334a45a8ff 127 {P7_3 , CAN_2, 5},
bogdanm 0:9b334a45a8ff 128 {P2_13 , CAN_3, 5},
bogdanm 0:9b334a45a8ff 129 {P4_3 , CAN_3, 4},
bogdanm 0:9b334a45a8ff 130 {P4_11 , CAN_4, 6},
bogdanm 0:9b334a45a8ff 131 {P8_10 , CAN_4, 5},
bogdanm 0:9b334a45a8ff 132 {NC , NC , 0}
bogdanm 0:9b334a45a8ff 133 };
bogdanm 0:9b334a45a8ff 134
bogdanm 0:9b334a45a8ff 135 static __IO uint32_t *CTR_MATCH[] = {
bogdanm 0:9b334a45a8ff 136 &RSCAN0C0CTR,
bogdanm 0:9b334a45a8ff 137 &RSCAN0C1CTR,
bogdanm 0:9b334a45a8ff 138 &RSCAN0C2CTR,
bogdanm 0:9b334a45a8ff 139 &RSCAN0C3CTR,
bogdanm 0:9b334a45a8ff 140 &RSCAN0C4CTR,
bogdanm 0:9b334a45a8ff 141 };
bogdanm 0:9b334a45a8ff 142
bogdanm 0:9b334a45a8ff 143 static __IO uint32_t *CFG_MATCH[] = {
bogdanm 0:9b334a45a8ff 144 &RSCAN0C0CFG,
bogdanm 0:9b334a45a8ff 145 &RSCAN0C1CFG,
bogdanm 0:9b334a45a8ff 146 &RSCAN0C2CFG,
bogdanm 0:9b334a45a8ff 147 &RSCAN0C3CFG,
bogdanm 0:9b334a45a8ff 148 &RSCAN0C4CFG,
bogdanm 0:9b334a45a8ff 149 };
bogdanm 0:9b334a45a8ff 150
bogdanm 0:9b334a45a8ff 151 static __IO uint32_t *RFCC_MATCH[] = {
bogdanm 0:9b334a45a8ff 152 &RSCAN0RFCC0,
bogdanm 0:9b334a45a8ff 153 &RSCAN0RFCC1,
bogdanm 0:9b334a45a8ff 154 &RSCAN0RFCC2,
bogdanm 0:9b334a45a8ff 155 &RSCAN0RFCC3,
bogdanm 0:9b334a45a8ff 156 &RSCAN0RFCC4,
bogdanm 0:9b334a45a8ff 157 &RSCAN0RFCC5,
bogdanm 0:9b334a45a8ff 158 &RSCAN0RFCC6,
bogdanm 0:9b334a45a8ff 159 &RSCAN0RFCC7
bogdanm 0:9b334a45a8ff 160 };
bogdanm 0:9b334a45a8ff 161
bogdanm 0:9b334a45a8ff 162 static __IO uint32_t *TXQCC_MATCH[] = {
bogdanm 0:9b334a45a8ff 163 &RSCAN0TXQCC0,
bogdanm 0:9b334a45a8ff 164 &RSCAN0TXQCC1,
bogdanm 0:9b334a45a8ff 165 &RSCAN0TXQCC2,
bogdanm 0:9b334a45a8ff 166 &RSCAN0TXQCC3,
bogdanm 0:9b334a45a8ff 167 &RSCAN0TXQCC4,
bogdanm 0:9b334a45a8ff 168 };
bogdanm 0:9b334a45a8ff 169
bogdanm 0:9b334a45a8ff 170 static __IO uint32_t *THLCC_MATCH[] = {
bogdanm 0:9b334a45a8ff 171 &RSCAN0THLCC0,
bogdanm 0:9b334a45a8ff 172 &RSCAN0THLCC1,
bogdanm 0:9b334a45a8ff 173 &RSCAN0THLCC2,
bogdanm 0:9b334a45a8ff 174 &RSCAN0THLCC3,
bogdanm 0:9b334a45a8ff 175 &RSCAN0THLCC4,
bogdanm 0:9b334a45a8ff 176 };
bogdanm 0:9b334a45a8ff 177
bogdanm 0:9b334a45a8ff 178 static __IO uint32_t *STS_MATCH[] = {
bogdanm 0:9b334a45a8ff 179 &RSCAN0C0STS,
bogdanm 0:9b334a45a8ff 180 &RSCAN0C1STS,
bogdanm 0:9b334a45a8ff 181 &RSCAN0C2STS,
bogdanm 0:9b334a45a8ff 182 &RSCAN0C3STS,
bogdanm 0:9b334a45a8ff 183 &RSCAN0C4STS,
bogdanm 0:9b334a45a8ff 184 };
bogdanm 0:9b334a45a8ff 185
bogdanm 0:9b334a45a8ff 186 static __IO uint32_t *ERFL_MATCH[] = {
bogdanm 0:9b334a45a8ff 187 &RSCAN0C0ERFL,
bogdanm 0:9b334a45a8ff 188 &RSCAN0C1ERFL,
bogdanm 0:9b334a45a8ff 189 &RSCAN0C2ERFL,
bogdanm 0:9b334a45a8ff 190 &RSCAN0C3ERFL,
bogdanm 0:9b334a45a8ff 191 &RSCAN0C4ERFL,
bogdanm 0:9b334a45a8ff 192 };
bogdanm 0:9b334a45a8ff 193
bogdanm 0:9b334a45a8ff 194 static __IO uint32_t *CFCC_TBL[CAN_NUM][CAN_SND_RCV] = {
bogdanm 0:9b334a45a8ff 195 { &RSCAN0CFCC0 , &RSCAN0CFCC1 },
bogdanm 0:9b334a45a8ff 196 { &RSCAN0CFCC3 , &RSCAN0CFCC4 },
bogdanm 0:9b334a45a8ff 197 { &RSCAN0CFCC6 , &RSCAN0CFCC7 },
bogdanm 0:9b334a45a8ff 198 { &RSCAN0CFCC9 , &RSCAN0CFCC10 },
bogdanm 0:9b334a45a8ff 199 { &RSCAN0CFCC12, &RSCAN0CFCC13 }
bogdanm 0:9b334a45a8ff 200 };
bogdanm 0:9b334a45a8ff 201
bogdanm 0:9b334a45a8ff 202 static __IO uint32_t *CFSTS_TBL[CAN_NUM][CAN_SND_RCV] = {
bogdanm 0:9b334a45a8ff 203 { &RSCAN0CFSTS0 , &RSCAN0CFSTS1 },
bogdanm 0:9b334a45a8ff 204 { &RSCAN0CFSTS3 , &RSCAN0CFSTS4 },
bogdanm 0:9b334a45a8ff 205 { &RSCAN0CFSTS6 , &RSCAN0CFSTS7 },
bogdanm 0:9b334a45a8ff 206 { &RSCAN0CFSTS9 , &RSCAN0CFSTS10 },
bogdanm 0:9b334a45a8ff 207 { &RSCAN0CFSTS12, &RSCAN0CFSTS13 }
bogdanm 0:9b334a45a8ff 208 };
bogdanm 0:9b334a45a8ff 209
bogdanm 0:9b334a45a8ff 210 static __IO uint32_t *CFPCTR_TBL[CAN_NUM][CAN_SND_RCV] = {
bogdanm 0:9b334a45a8ff 211 { &RSCAN0CFPCTR0 , &RSCAN0CFPCTR1 },
bogdanm 0:9b334a45a8ff 212 { &RSCAN0CFPCTR3 , &RSCAN0CFPCTR4 },
bogdanm 0:9b334a45a8ff 213 { &RSCAN0CFPCTR6 , &RSCAN0CFPCTR7 },
bogdanm 0:9b334a45a8ff 214 { &RSCAN0CFPCTR9 , &RSCAN0CFPCTR10 },
bogdanm 0:9b334a45a8ff 215 { &RSCAN0CFPCTR12, &RSCAN0CFPCTR13 }
bogdanm 0:9b334a45a8ff 216 };
bogdanm 0:9b334a45a8ff 217
bogdanm 0:9b334a45a8ff 218 static __IO uint32_t *CFID_TBL[CAN_NUM][CAN_SND_RCV] = {
bogdanm 0:9b334a45a8ff 219 { &RSCAN0CFID0 , &RSCAN0CFID1 },
bogdanm 0:9b334a45a8ff 220 { &RSCAN0CFID3 , &RSCAN0CFID4 },
bogdanm 0:9b334a45a8ff 221 { &RSCAN0CFID6 , &RSCAN0CFID7 },
bogdanm 0:9b334a45a8ff 222 { &RSCAN0CFID9 , &RSCAN0CFID10 },
bogdanm 0:9b334a45a8ff 223 { &RSCAN0CFID12, &RSCAN0CFID13 }
bogdanm 0:9b334a45a8ff 224 };
bogdanm 0:9b334a45a8ff 225
bogdanm 0:9b334a45a8ff 226 static __IO uint32_t *CFPTR_TBL[CAN_NUM][CAN_SND_RCV] = {
bogdanm 0:9b334a45a8ff 227 { &RSCAN0CFPTR0 , &RSCAN0CFPTR1 },
bogdanm 0:9b334a45a8ff 228 { &RSCAN0CFPTR3 , &RSCAN0CFPTR4 },
bogdanm 0:9b334a45a8ff 229 { &RSCAN0CFPTR6 , &RSCAN0CFPTR7 },
bogdanm 0:9b334a45a8ff 230 { &RSCAN0CFPTR9 , &RSCAN0CFPTR10 },
bogdanm 0:9b334a45a8ff 231 { &RSCAN0CFPTR12, &RSCAN0CFPTR13 }
bogdanm 0:9b334a45a8ff 232 };
bogdanm 0:9b334a45a8ff 233
bogdanm 0:9b334a45a8ff 234 static __IO uint32_t *CFDF0_TBL[CAN_NUM][CAN_SND_RCV] = {
bogdanm 0:9b334a45a8ff 235 { &RSCAN0CFDF00 , &RSCAN0CFDF01 },
bogdanm 0:9b334a45a8ff 236 { &RSCAN0CFDF03 , &RSCAN0CFDF04 },
bogdanm 0:9b334a45a8ff 237 { &RSCAN0CFDF06 , &RSCAN0CFDF07 },
bogdanm 0:9b334a45a8ff 238 { &RSCAN0CFDF09 , &RSCAN0CFDF010 },
bogdanm 0:9b334a45a8ff 239 { &RSCAN0CFDF012, &RSCAN0CFDF013 }
bogdanm 0:9b334a45a8ff 240 };
bogdanm 0:9b334a45a8ff 241
bogdanm 0:9b334a45a8ff 242 static __IO uint32_t *CFDF1_TBL[CAN_NUM][CAN_SND_RCV] = {
bogdanm 0:9b334a45a8ff 243 { &RSCAN0CFDF10 , &RSCAN0CFDF11 },
bogdanm 0:9b334a45a8ff 244 { &RSCAN0CFDF13 , &RSCAN0CFDF14 },
bogdanm 0:9b334a45a8ff 245 { &RSCAN0CFDF16 , &RSCAN0CFDF17 },
bogdanm 0:9b334a45a8ff 246 { &RSCAN0CFDF19 , &RSCAN0CFDF110 },
bogdanm 0:9b334a45a8ff 247 { &RSCAN0CFDF112, &RSCAN0CFDF113 }
bogdanm 0:9b334a45a8ff 248 };
bogdanm 0:9b334a45a8ff 249
bogdanm 0:9b334a45a8ff 250 static const can_info_int_t can_int_info[CAN_NUM][IRQ_NUM] =
bogdanm 0:9b334a45a8ff 251 {
bogdanm 0:9b334a45a8ff 252 { /* ch0 */
bogdanm 0:9b334a45a8ff 253 { INTRCAN0REC_IRQn, can0_rec_irq }, /* RxIrq */
bogdanm 0:9b334a45a8ff 254 { INTRCAN0TRX_IRQn, can0_trx_irq }, /* TxIrq */
bogdanm 0:9b334a45a8ff 255 { INTRCAN0ERR_IRQn, can0_err_warning_irq }, /* EwIrq */
bogdanm 0:9b334a45a8ff 256 { INTRCAN0ERR_IRQn, can0_overrun_irq }, /* DoIrq */
bogdanm 0:9b334a45a8ff 257 { INTRCAN0ERR_IRQn, NULL }, /* WuIrq(not supported) */
bogdanm 0:9b334a45a8ff 258 { INTRCAN0ERR_IRQn, can0_passive_irq }, /* EpIrq */
bogdanm 0:9b334a45a8ff 259 { INTRCAN0ERR_IRQn, can0_arb_lost_irq }, /* AlIrq */
bogdanm 0:9b334a45a8ff 260 { INTRCAN0ERR_IRQn, can0_bus_err_irq } /* BeIrq */
bogdanm 0:9b334a45a8ff 261 },
bogdanm 0:9b334a45a8ff 262 { /* ch1 */
bogdanm 0:9b334a45a8ff 263 { INTRCAN1REC_IRQn, can1_rec_irq }, /* RxIrq */
bogdanm 0:9b334a45a8ff 264 { INTRCAN1TRX_IRQn, can1_trx_irq }, /* TxIrq */
bogdanm 0:9b334a45a8ff 265 { INTRCAN1ERR_IRQn, can1_err_warning_irq }, /* EwIrq */
bogdanm 0:9b334a45a8ff 266 { INTRCAN1ERR_IRQn, can1_overrun_irq }, /* DoIrq */
bogdanm 0:9b334a45a8ff 267 { INTRCAN1ERR_IRQn, NULL }, /* WuIrq(not supported) */
bogdanm 0:9b334a45a8ff 268 { INTRCAN1ERR_IRQn, can1_passive_irq }, /* EpIrq */
bogdanm 0:9b334a45a8ff 269 { INTRCAN1ERR_IRQn, can1_arb_lost_irq }, /* AlIrq */
bogdanm 0:9b334a45a8ff 270 { INTRCAN1ERR_IRQn, can1_bus_err_irq } /* BeIrq */
bogdanm 0:9b334a45a8ff 271 },
bogdanm 0:9b334a45a8ff 272 { /* ch2 */
bogdanm 0:9b334a45a8ff 273 { INTRCAN2REC_IRQn, can2_rec_irq }, /* RxIrq */
bogdanm 0:9b334a45a8ff 274 { INTRCAN2TRX_IRQn, can2_trx_irq }, /* TxIrq */
bogdanm 0:9b334a45a8ff 275 { INTRCAN2ERR_IRQn, can2_err_warning_irq }, /* EwIrq */
bogdanm 0:9b334a45a8ff 276 { INTRCAN2ERR_IRQn, can2_overrun_irq }, /* DoIrq */
bogdanm 0:9b334a45a8ff 277 { INTRCAN2ERR_IRQn, NULL }, /* WuIrq(not supported) */
bogdanm 0:9b334a45a8ff 278 { INTRCAN2ERR_IRQn, can2_passive_irq }, /* EpIrq */
bogdanm 0:9b334a45a8ff 279 { INTRCAN2ERR_IRQn, can2_arb_lost_irq }, /* AlIrq */
bogdanm 0:9b334a45a8ff 280 { INTRCAN2ERR_IRQn, can2_bus_err_irq } /* BeIrq */
bogdanm 0:9b334a45a8ff 281 },
bogdanm 0:9b334a45a8ff 282 { /* ch3 */
bogdanm 0:9b334a45a8ff 283 { INTRCAN3REC_IRQn, can3_rec_irq }, /* RxIrq */
bogdanm 0:9b334a45a8ff 284 { INTRCAN3TRX_IRQn, can3_trx_irq }, /* TxIrq */
bogdanm 0:9b334a45a8ff 285 { INTRCAN3ERR_IRQn, can3_err_warning_irq }, /* EwIrq */
bogdanm 0:9b334a45a8ff 286 { INTRCAN3ERR_IRQn, can3_overrun_irq }, /* DoIrq */
bogdanm 0:9b334a45a8ff 287 { INTRCAN3ERR_IRQn, NULL }, /* WuIrq(not supported) */
bogdanm 0:9b334a45a8ff 288 { INTRCAN3ERR_IRQn, can3_passive_irq }, /* EpIrq */
bogdanm 0:9b334a45a8ff 289 { INTRCAN3ERR_IRQn, can3_arb_lost_irq }, /* AlIrq */
bogdanm 0:9b334a45a8ff 290 { INTRCAN3ERR_IRQn, can3_bus_err_irq } /* BeIrq */
bogdanm 0:9b334a45a8ff 291 },
bogdanm 0:9b334a45a8ff 292 { /* ch4 */
bogdanm 0:9b334a45a8ff 293 { INTRCAN4REC_IRQn, can4_rec_irq }, /* RxIrq */
bogdanm 0:9b334a45a8ff 294 { INTRCAN4TRX_IRQn, can4_trx_irq }, /* TxIrq */
bogdanm 0:9b334a45a8ff 295 { INTRCAN4ERR_IRQn, can4_err_warning_irq }, /* EwIrq */
bogdanm 0:9b334a45a8ff 296 { INTRCAN4ERR_IRQn, can4_overrun_irq }, /* DoIrq */
bogdanm 0:9b334a45a8ff 297 { INTRCAN4ERR_IRQn, NULL }, /* WuIrq(not supported) */
bogdanm 0:9b334a45a8ff 298 { INTRCAN4ERR_IRQn, can4_passive_irq }, /* EpIrq */
bogdanm 0:9b334a45a8ff 299 { INTRCAN4ERR_IRQn, can4_arb_lost_irq }, /* AlIrq */
bogdanm 0:9b334a45a8ff 300 { INTRCAN4ERR_IRQn, can4_bus_err_irq } /* BeIrq */
bogdanm 0:9b334a45a8ff 301 }
bogdanm 0:9b334a45a8ff 302 };
bogdanm 0:9b334a45a8ff 303
bogdanm 0:9b334a45a8ff 304 static __IO uint32_t *dmy_gaflid = &RSCAN0GAFLID0;
bogdanm 0:9b334a45a8ff 305 static __IO uint32_t *dmy_gaflm = &RSCAN0GAFLM0;
bogdanm 0:9b334a45a8ff 306 static __IO uint32_t *dmy_gaflp0 = &RSCAN0GAFLP00;
bogdanm 0:9b334a45a8ff 307 static __IO uint32_t *dmy_gaflp1 = &RSCAN0GAFLP10;
bogdanm 0:9b334a45a8ff 308
bogdanm 0:9b334a45a8ff 309 void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
bogdanm 0:9b334a45a8ff 310 irq_handler = handler;
bogdanm 0:9b334a45a8ff 311 can_irq_id[obj->ch] = id;
bogdanm 0:9b334a45a8ff 312 }
bogdanm 0:9b334a45a8ff 313
bogdanm 0:9b334a45a8ff 314 void can_irq_free(can_t *obj) {
bogdanm 0:9b334a45a8ff 315 can_irq_id[obj->ch] = 0;
bogdanm 0:9b334a45a8ff 316 }
bogdanm 0:9b334a45a8ff 317
bogdanm 0:9b334a45a8ff 318 void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
bogdanm 0:9b334a45a8ff 319 __IO uint32_t *dmy_ctr;
bogdanm 0:9b334a45a8ff 320
bogdanm 0:9b334a45a8ff 321 /* Wake-up Irq is not supported */
bogdanm 0:9b334a45a8ff 322 if (type != IRQ_WAKEUP) {
bogdanm 0:9b334a45a8ff 323 if (enable) {
bogdanm 0:9b334a45a8ff 324 dmy_ctr = CTR_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 325 if (type == IRQ_ERROR) {
bogdanm 0:9b334a45a8ff 326 /* EWIE interrupts is enable */
bogdanm 0:9b334a45a8ff 327 *dmy_ctr |= 0x00000200;
bogdanm 0:9b334a45a8ff 328 } else if (type == IRQ_OVERRUN) {
bogdanm 0:9b334a45a8ff 329 /* OLIE interrupts is enable */
bogdanm 0:9b334a45a8ff 330 *dmy_ctr |= 0x00002000;
bogdanm 0:9b334a45a8ff 331 } else if (type == IRQ_PASSIVE) {
bogdanm 0:9b334a45a8ff 332 /* EPIE interrupts is enable */
bogdanm 0:9b334a45a8ff 333 *dmy_ctr |= 0x00000400;
bogdanm 0:9b334a45a8ff 334 } else if (type == IRQ_ARB) {
bogdanm 0:9b334a45a8ff 335 /* ALIE interrupts is enable */
bogdanm 0:9b334a45a8ff 336 *dmy_ctr |= 0x00008000;
bogdanm 0:9b334a45a8ff 337 } else if (type == IRQ_BUS) {
bogdanm 0:9b334a45a8ff 338 /* BEIE interrupts is enable */
bogdanm 0:9b334a45a8ff 339 *dmy_ctr |= 0x00000100;
bogdanm 0:9b334a45a8ff 340 }
bogdanm 0:9b334a45a8ff 341 InterruptHandlerRegister(can_int_info[obj->ch][type].int_num, can_int_info[obj->ch][type].handler);
bogdanm 0:9b334a45a8ff 342 GIC_SetPriority(can_int_info[obj->ch][type].int_num, 5);
bogdanm 0:9b334a45a8ff 343 GIC_EnableIRQ(can_int_info[obj->ch][type].int_num);
bogdanm 0:9b334a45a8ff 344 } else {
bogdanm 0:9b334a45a8ff 345 GIC_DisableIRQ(can_int_info[obj->ch][type].int_num);
bogdanm 0:9b334a45a8ff 346 }
bogdanm 0:9b334a45a8ff 347 }
bogdanm 0:9b334a45a8ff 348 }
bogdanm 0:9b334a45a8ff 349
bogdanm 0:9b334a45a8ff 350 static void can_rec_irq(uint32_t ch) {
bogdanm 0:9b334a45a8ff 351 __IO uint32_t *dmy_cfsts;
bogdanm 0:9b334a45a8ff 352
bogdanm 0:9b334a45a8ff 353 dmy_cfsts = CFSTS_TBL[ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 354 *dmy_cfsts &= 0xFFFFFFF7; // Clear CFRXIF
bogdanm 0:9b334a45a8ff 355
bogdanm 0:9b334a45a8ff 356 irq_handler(can_irq_id[ch], IRQ_RX);
bogdanm 0:9b334a45a8ff 357 }
bogdanm 0:9b334a45a8ff 358
bogdanm 0:9b334a45a8ff 359 static void can_trx_irq(uint32_t ch) {
bogdanm 0:9b334a45a8ff 360 __IO uint32_t *dmy_cfsts;
bogdanm 0:9b334a45a8ff 361
bogdanm 0:9b334a45a8ff 362 dmy_cfsts = CFSTS_TBL[ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 363 *dmy_cfsts &= 0xFFFFFFEF; // Clear CFTXIF
bogdanm 0:9b334a45a8ff 364
bogdanm 0:9b334a45a8ff 365 irq_handler(can_irq_id[ch], IRQ_TX);
bogdanm 0:9b334a45a8ff 366 }
bogdanm 0:9b334a45a8ff 367
bogdanm 0:9b334a45a8ff 368 static void can_err_irq(uint32_t ch, CanIrqType type) {
bogdanm 0:9b334a45a8ff 369 __IO uint32_t *dmy_erfl;
bogdanm 0:9b334a45a8ff 370 int val = 1;
bogdanm 0:9b334a45a8ff 371
bogdanm 0:9b334a45a8ff 372 dmy_erfl = ERFL_MATCH[ch];
bogdanm 0:9b334a45a8ff 373 switch (type) {
bogdanm 0:9b334a45a8ff 374 case IRQ_ERROR:
bogdanm 0:9b334a45a8ff 375 *dmy_erfl &= 0xFFFFFFFD; // Clear EWF
bogdanm 0:9b334a45a8ff 376 break;
bogdanm 0:9b334a45a8ff 377 case IRQ_OVERRUN:
bogdanm 0:9b334a45a8ff 378 *dmy_erfl &= 0xFFFFFFDF; // Clear OVLF
bogdanm 0:9b334a45a8ff 379 break;
bogdanm 0:9b334a45a8ff 380 case IRQ_PASSIVE:
bogdanm 0:9b334a45a8ff 381 *dmy_erfl &= 0xFFFFFFFB; // Clear EPF
bogdanm 0:9b334a45a8ff 382 break;
bogdanm 0:9b334a45a8ff 383 case IRQ_ARB:
bogdanm 0:9b334a45a8ff 384 *dmy_erfl &= 0xFFFFFF7F; // Clear ALF
bogdanm 0:9b334a45a8ff 385 break;
bogdanm 0:9b334a45a8ff 386 case IRQ_BUS:
bogdanm 0:9b334a45a8ff 387 *dmy_erfl &= 0xFFFF00FF; // Clear ADERRAB0ERRAB1ERRACERRAAERRAFERRASERR
bogdanm 0:9b334a45a8ff 388 *dmy_erfl &= 0xFFFFFFFE; // Clear BEF
bogdanm 0:9b334a45a8ff 389 break;
bogdanm 0:9b334a45a8ff 390 case IRQ_WAKEUP:
bogdanm 0:9b334a45a8ff 391 /* not supported */
bogdanm 0:9b334a45a8ff 392 /* fall through */
bogdanm 0:9b334a45a8ff 393 default:
bogdanm 0:9b334a45a8ff 394 val = 0;
bogdanm 0:9b334a45a8ff 395 break;
bogdanm 0:9b334a45a8ff 396 }
bogdanm 0:9b334a45a8ff 397 if (val == 1) {
bogdanm 0:9b334a45a8ff 398 irq_handler(can_irq_id[ch], type);
bogdanm 0:9b334a45a8ff 399 }
bogdanm 0:9b334a45a8ff 400 }
bogdanm 0:9b334a45a8ff 401
bogdanm 0:9b334a45a8ff 402 static void can0_rec_irq(void) {
bogdanm 0:9b334a45a8ff 403 can_rec_irq(CAN_0);
bogdanm 0:9b334a45a8ff 404 }
bogdanm 0:9b334a45a8ff 405
bogdanm 0:9b334a45a8ff 406 static void can1_rec_irq(void) {
bogdanm 0:9b334a45a8ff 407 can_rec_irq(CAN_1);
bogdanm 0:9b334a45a8ff 408 }
bogdanm 0:9b334a45a8ff 409
bogdanm 0:9b334a45a8ff 410 static void can2_rec_irq(void) {
bogdanm 0:9b334a45a8ff 411 can_rec_irq(CAN_2);
bogdanm 0:9b334a45a8ff 412 }
bogdanm 0:9b334a45a8ff 413
bogdanm 0:9b334a45a8ff 414 static void can3_rec_irq(void) {
bogdanm 0:9b334a45a8ff 415 can_rec_irq(CAN_3);
bogdanm 0:9b334a45a8ff 416 }
bogdanm 0:9b334a45a8ff 417
bogdanm 0:9b334a45a8ff 418 static void can4_rec_irq(void) {
bogdanm 0:9b334a45a8ff 419 can_rec_irq(CAN_4);
bogdanm 0:9b334a45a8ff 420 }
bogdanm 0:9b334a45a8ff 421
bogdanm 0:9b334a45a8ff 422 static void can0_trx_irq(void) {
bogdanm 0:9b334a45a8ff 423 can_trx_irq(CAN_0);
bogdanm 0:9b334a45a8ff 424 }
bogdanm 0:9b334a45a8ff 425
bogdanm 0:9b334a45a8ff 426 static void can1_trx_irq(void) {
bogdanm 0:9b334a45a8ff 427 can_trx_irq(CAN_1);
bogdanm 0:9b334a45a8ff 428 }
bogdanm 0:9b334a45a8ff 429
bogdanm 0:9b334a45a8ff 430 static void can2_trx_irq(void) {
bogdanm 0:9b334a45a8ff 431 can_trx_irq(CAN_2);
bogdanm 0:9b334a45a8ff 432 }
bogdanm 0:9b334a45a8ff 433
bogdanm 0:9b334a45a8ff 434 static void can3_trx_irq(void) {
bogdanm 0:9b334a45a8ff 435 can_trx_irq(CAN_3);
bogdanm 0:9b334a45a8ff 436 }
bogdanm 0:9b334a45a8ff 437
bogdanm 0:9b334a45a8ff 438 static void can4_trx_irq(void) {
bogdanm 0:9b334a45a8ff 439 can_trx_irq(CAN_4);
bogdanm 0:9b334a45a8ff 440 }
bogdanm 0:9b334a45a8ff 441
bogdanm 0:9b334a45a8ff 442 static void can0_err_warning_irq(void) {
bogdanm 0:9b334a45a8ff 443 can_err_irq(CAN_0, IRQ_ERROR);
bogdanm 0:9b334a45a8ff 444 }
bogdanm 0:9b334a45a8ff 445
bogdanm 0:9b334a45a8ff 446 static void can1_err_warning_irq(void) {
bogdanm 0:9b334a45a8ff 447 can_err_irq(CAN_1, IRQ_ERROR);
bogdanm 0:9b334a45a8ff 448 }
bogdanm 0:9b334a45a8ff 449
bogdanm 0:9b334a45a8ff 450 static void can2_err_warning_irq(void) {
bogdanm 0:9b334a45a8ff 451 can_err_irq(CAN_2, IRQ_ERROR);
bogdanm 0:9b334a45a8ff 452 }
bogdanm 0:9b334a45a8ff 453
bogdanm 0:9b334a45a8ff 454 static void can3_err_warning_irq(void) {
bogdanm 0:9b334a45a8ff 455 can_err_irq(CAN_3, IRQ_ERROR);
bogdanm 0:9b334a45a8ff 456 }
bogdanm 0:9b334a45a8ff 457
bogdanm 0:9b334a45a8ff 458 static void can4_err_warning_irq(void) {
bogdanm 0:9b334a45a8ff 459 can_err_irq(CAN_4, IRQ_ERROR);
bogdanm 0:9b334a45a8ff 460 }
bogdanm 0:9b334a45a8ff 461
bogdanm 0:9b334a45a8ff 462 static void can0_overrun_irq(void) {
bogdanm 0:9b334a45a8ff 463 can_err_irq(CAN_0, IRQ_OVERRUN);
bogdanm 0:9b334a45a8ff 464 }
bogdanm 0:9b334a45a8ff 465
bogdanm 0:9b334a45a8ff 466 static void can1_overrun_irq(void) {
bogdanm 0:9b334a45a8ff 467 can_err_irq(CAN_1, IRQ_OVERRUN);
bogdanm 0:9b334a45a8ff 468 }
bogdanm 0:9b334a45a8ff 469
bogdanm 0:9b334a45a8ff 470 static void can2_overrun_irq(void) {
bogdanm 0:9b334a45a8ff 471 can_err_irq(CAN_2, IRQ_OVERRUN);
bogdanm 0:9b334a45a8ff 472 }
bogdanm 0:9b334a45a8ff 473
bogdanm 0:9b334a45a8ff 474 static void can3_overrun_irq(void) {
bogdanm 0:9b334a45a8ff 475 can_err_irq(CAN_3, IRQ_OVERRUN);
bogdanm 0:9b334a45a8ff 476 }
bogdanm 0:9b334a45a8ff 477
bogdanm 0:9b334a45a8ff 478 static void can4_overrun_irq(void) {
bogdanm 0:9b334a45a8ff 479 can_err_irq(CAN_4, IRQ_OVERRUN);
bogdanm 0:9b334a45a8ff 480 }
bogdanm 0:9b334a45a8ff 481
bogdanm 0:9b334a45a8ff 482 static void can0_passive_irq(void) {
bogdanm 0:9b334a45a8ff 483 can_err_irq(CAN_0, IRQ_PASSIVE);
bogdanm 0:9b334a45a8ff 484 }
bogdanm 0:9b334a45a8ff 485
bogdanm 0:9b334a45a8ff 486 static void can1_passive_irq(void) {
bogdanm 0:9b334a45a8ff 487 can_err_irq(CAN_1, IRQ_PASSIVE);
bogdanm 0:9b334a45a8ff 488 }
bogdanm 0:9b334a45a8ff 489
bogdanm 0:9b334a45a8ff 490 static void can2_passive_irq(void) {
bogdanm 0:9b334a45a8ff 491 can_err_irq(CAN_2, IRQ_PASSIVE);
bogdanm 0:9b334a45a8ff 492 }
bogdanm 0:9b334a45a8ff 493
bogdanm 0:9b334a45a8ff 494 static void can3_passive_irq(void) {
bogdanm 0:9b334a45a8ff 495 can_err_irq(CAN_3, IRQ_PASSIVE);
bogdanm 0:9b334a45a8ff 496 }
bogdanm 0:9b334a45a8ff 497
bogdanm 0:9b334a45a8ff 498 static void can4_passive_irq(void) {
bogdanm 0:9b334a45a8ff 499 can_err_irq(CAN_4, IRQ_PASSIVE);
bogdanm 0:9b334a45a8ff 500 }
bogdanm 0:9b334a45a8ff 501
bogdanm 0:9b334a45a8ff 502 static void can0_arb_lost_irq(void) {
bogdanm 0:9b334a45a8ff 503 can_err_irq(CAN_0, IRQ_ARB);
bogdanm 0:9b334a45a8ff 504 }
bogdanm 0:9b334a45a8ff 505
bogdanm 0:9b334a45a8ff 506 static void can1_arb_lost_irq(void) {
bogdanm 0:9b334a45a8ff 507 can_err_irq(CAN_1, IRQ_ARB);
bogdanm 0:9b334a45a8ff 508 }
bogdanm 0:9b334a45a8ff 509
bogdanm 0:9b334a45a8ff 510 static void can2_arb_lost_irq(void) {
bogdanm 0:9b334a45a8ff 511 can_err_irq(CAN_2, IRQ_ARB);
bogdanm 0:9b334a45a8ff 512 }
bogdanm 0:9b334a45a8ff 513
bogdanm 0:9b334a45a8ff 514 static void can3_arb_lost_irq(void) {
bogdanm 0:9b334a45a8ff 515 can_err_irq(CAN_3, IRQ_ARB);
bogdanm 0:9b334a45a8ff 516 }
bogdanm 0:9b334a45a8ff 517
bogdanm 0:9b334a45a8ff 518 static void can4_arb_lost_irq(void) {
bogdanm 0:9b334a45a8ff 519 can_err_irq(CAN_4, IRQ_ARB);
bogdanm 0:9b334a45a8ff 520 }
bogdanm 0:9b334a45a8ff 521
bogdanm 0:9b334a45a8ff 522 static void can0_bus_err_irq(void) {
bogdanm 0:9b334a45a8ff 523 can_err_irq(CAN_0, IRQ_BUS);
bogdanm 0:9b334a45a8ff 524 }
bogdanm 0:9b334a45a8ff 525
bogdanm 0:9b334a45a8ff 526 static void can1_bus_err_irq(void) {
bogdanm 0:9b334a45a8ff 527 can_err_irq(CAN_1, IRQ_BUS);
bogdanm 0:9b334a45a8ff 528 }
bogdanm 0:9b334a45a8ff 529
bogdanm 0:9b334a45a8ff 530 static void can2_bus_err_irq(void) {
bogdanm 0:9b334a45a8ff 531 can_err_irq(CAN_2, IRQ_BUS);
bogdanm 0:9b334a45a8ff 532 }
bogdanm 0:9b334a45a8ff 533
bogdanm 0:9b334a45a8ff 534 static void can3_bus_err_irq(void) {
bogdanm 0:9b334a45a8ff 535 can_err_irq(CAN_3, IRQ_BUS);
bogdanm 0:9b334a45a8ff 536 }
bogdanm 0:9b334a45a8ff 537
bogdanm 0:9b334a45a8ff 538 static void can4_bus_err_irq(void) {
bogdanm 0:9b334a45a8ff 539 can_err_irq(CAN_4, IRQ_BUS);
bogdanm 0:9b334a45a8ff 540 }
bogdanm 0:9b334a45a8ff 541
bogdanm 0:9b334a45a8ff 542 void can_init(can_t *obj, PinName rd, PinName td) {
bogdanm 0:9b334a45a8ff 543 __IO uint32_t *dmy_ctr;
bogdanm 0:9b334a45a8ff 544
bogdanm 0:9b334a45a8ff 545 /* determine the CAN to use */
bogdanm 0:9b334a45a8ff 546 uint32_t can_rx = pinmap_peripheral(rd, PinMap_CAN_RD);
bogdanm 0:9b334a45a8ff 547 uint32_t can_tx = pinmap_peripheral(td, PinMap_CAN_TD);
bogdanm 0:9b334a45a8ff 548 obj->ch = pinmap_merge(can_tx, can_rx);
bogdanm 0:9b334a45a8ff 549 MBED_ASSERT((int)obj->ch != NC);
bogdanm 0:9b334a45a8ff 550
bogdanm 0:9b334a45a8ff 551 /* enable CAN clock */
bogdanm 0:9b334a45a8ff 552 CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP32);
bogdanm 0:9b334a45a8ff 553 /* Has CAN RAM initialisation completed ? */
bogdanm 0:9b334a45a8ff 554 while ((RSCAN0GSTS & 0x08) == 0x08) {
bogdanm 0:9b334a45a8ff 555 __NOP();
bogdanm 0:9b334a45a8ff 556 }
bogdanm 0:9b334a45a8ff 557 /* clear Global Stop mode bit */
bogdanm 0:9b334a45a8ff 558 RSCAN0GCTR &= 0xFFFFFFFB;
bogdanm 0:9b334a45a8ff 559 /* clear Channel Stop mode bit */
bogdanm 0:9b334a45a8ff 560 dmy_ctr = CTR_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 561 *dmy_ctr &= 0xFFFFFFFB;
bogdanm 0:9b334a45a8ff 562 /* Enter global reset mode */
bogdanm 0:9b334a45a8ff 563 can_set_global_mode(GL_RESET);
bogdanm 0:9b334a45a8ff 564 /* Enter channel reset mode */
bogdanm 0:9b334a45a8ff 565 can_set_channel_mode(obj->ch, CH_RESET);
bogdanm 0:9b334a45a8ff 566 /* reset register */
bogdanm 0:9b334a45a8ff 567 can_reset_reg(obj);
bogdanm 0:9b334a45a8ff 568
bogdanm 0:9b334a45a8ff 569 can_initialized[obj->ch] = 1;
bogdanm 0:9b334a45a8ff 570 /* reconfigure channel which is already initialized */
bogdanm 0:9b334a45a8ff 571 can_reconfigure_channel();
bogdanm 0:9b334a45a8ff 572
bogdanm 0:9b334a45a8ff 573 /* pin out the can pins */
bogdanm 0:9b334a45a8ff 574 pinmap_pinout(rd, PinMap_CAN_RD);
bogdanm 0:9b334a45a8ff 575 pinmap_pinout(td, PinMap_CAN_TD);
bogdanm 0:9b334a45a8ff 576 }
bogdanm 0:9b334a45a8ff 577
bogdanm 0:9b334a45a8ff 578 void can_free(can_t *obj) {
bogdanm 0:9b334a45a8ff 579 /* disable CAN clock */
bogdanm 0:9b334a45a8ff 580 CPGSTBCR3 |= CPG_STBCR3_BIT_MSTP32;
bogdanm 0:9b334a45a8ff 581 }
bogdanm 0:9b334a45a8ff 582
bogdanm 0:9b334a45a8ff 583 int can_frequency(can_t *obj, int f) {
bogdanm 0:9b334a45a8ff 584 int retval = 0;
bogdanm 0:9b334a45a8ff 585
bogdanm 0:9b334a45a8ff 586 if (f <= 1000000) {
bogdanm 0:9b334a45a8ff 587 /* less than 1Mhz */
bogdanm 0:9b334a45a8ff 588 /* set Channel Reset mode */
bogdanm 0:9b334a45a8ff 589 can_set_channel_mode(obj->ch, CH_RESET);
bogdanm 0:9b334a45a8ff 590 can_set_frequency(obj, f);
bogdanm 0:9b334a45a8ff 591 /* set Channel Communication mode */
bogdanm 0:9b334a45a8ff 592 can_set_channel_mode(obj->ch, CH_COMM);
bogdanm 0:9b334a45a8ff 593 retval = 1;
bogdanm 0:9b334a45a8ff 594 }
bogdanm 0:9b334a45a8ff 595
bogdanm 0:9b334a45a8ff 596 return retval;
bogdanm 0:9b334a45a8ff 597 }
bogdanm 0:9b334a45a8ff 598
bogdanm 0:9b334a45a8ff 599 void can_reset(can_t *obj) {
bogdanm 0:9b334a45a8ff 600 /* Enter global reset mode */
bogdanm 0:9b334a45a8ff 601 can_set_global_mode(GL_RESET);
bogdanm 0:9b334a45a8ff 602 /* Enter channel reset mode */
bogdanm 0:9b334a45a8ff 603 can_set_channel_mode(obj->ch, CH_RESET);
bogdanm 0:9b334a45a8ff 604 /* reset register */
bogdanm 0:9b334a45a8ff 605 can_reset_reg(obj);
bogdanm 0:9b334a45a8ff 606 /* reconfigure channel which is already initialized */
bogdanm 0:9b334a45a8ff 607 can_reconfigure_channel();
bogdanm 0:9b334a45a8ff 608 }
bogdanm 0:9b334a45a8ff 609
bogdanm 0:9b334a45a8ff 610 int can_write(can_t *obj, CAN_Message msg, int cc) {
bogdanm 0:9b334a45a8ff 611 __IO uint32_t *dmy_sts;
bogdanm 0:9b334a45a8ff 612 __IO uint32_t *dmy_cfsts;
bogdanm 0:9b334a45a8ff 613 __IO uint32_t *dmy_cfid;
bogdanm 0:9b334a45a8ff 614 __IO uint32_t *dmy_cfptr;
bogdanm 0:9b334a45a8ff 615 __IO uint32_t *dmy_cfdf0;
bogdanm 0:9b334a45a8ff 616 __IO uint32_t *dmy_cfdf1;
bogdanm 0:9b334a45a8ff 617 __IO uint32_t *dmy_cfpctr;
bogdanm 0:9b334a45a8ff 618 int retval = 0;
bogdanm 0:9b334a45a8ff 619
bogdanm 0:9b334a45a8ff 620 /* Wait to become channel communication mode */
bogdanm 0:9b334a45a8ff 621 dmy_sts = STS_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 622 while ((*dmy_sts & 0x07) != 0) {
bogdanm 0:9b334a45a8ff 623 __NOP();
bogdanm 0:9b334a45a8ff 624 }
bogdanm 0:9b334a45a8ff 625
bogdanm 0:9b334a45a8ff 626 if (((msg.format == CANStandard) && (msg.id <= 0x07FF)) || ((msg.format == CANExtended) && (msg.id <= 0x03FFFF))) {
bogdanm 0:9b334a45a8ff 627 /* send/receive FIFO buffer isn't full */
bogdanm 0:9b334a45a8ff 628 dmy_cfsts = CFSTS_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 629 if ((*dmy_cfsts & 0x02) != 0x02) {
bogdanm 0:9b334a45a8ff 630 /* set format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
bogdanm 0:9b334a45a8ff 631 dmy_cfid = CFID_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 632 *dmy_cfid = ((msg.format << 31) | (msg.type << 30));
bogdanm 0:9b334a45a8ff 633 if (msg.format == CANStandard) {
bogdanm 0:9b334a45a8ff 634 *dmy_cfid |= (msg.id & 0x07FF);
bogdanm 0:9b334a45a8ff 635 } else {
bogdanm 0:9b334a45a8ff 636 *dmy_cfid |= ((msg.id & 0x03FFFF) << 11);
bogdanm 0:9b334a45a8ff 637 }
bogdanm 0:9b334a45a8ff 638 /* set length */
bogdanm 0:9b334a45a8ff 639 dmy_cfptr = CFPTR_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 640 *dmy_cfptr = msg.len << 28;
bogdanm 0:9b334a45a8ff 641 /* set data */
bogdanm 0:9b334a45a8ff 642 dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 643 memcpy((void *)dmy_cfdf0, &msg.data[0], 4);
bogdanm 0:9b334a45a8ff 644 dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 645 memcpy((void *)dmy_cfdf1, &msg.data[4], 4);
bogdanm 0:9b334a45a8ff 646 /* send request */
bogdanm 0:9b334a45a8ff 647 dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 648 *dmy_cfpctr = 0xFF;
bogdanm 0:9b334a45a8ff 649 retval = 1;
bogdanm 0:9b334a45a8ff 650 }
bogdanm 0:9b334a45a8ff 651 }
bogdanm 0:9b334a45a8ff 652
bogdanm 0:9b334a45a8ff 653 return retval;
bogdanm 0:9b334a45a8ff 654 }
bogdanm 0:9b334a45a8ff 655
bogdanm 0:9b334a45a8ff 656 int can_read(can_t *obj, CAN_Message *msg, int handle) {
bogdanm 0:9b334a45a8ff 657 __IO uint32_t *dmy_sts;
bogdanm 0:9b334a45a8ff 658 __IO uint32_t *dmy_cfsts;
bogdanm 0:9b334a45a8ff 659 __IO uint32_t *dmy_cfid;
bogdanm 0:9b334a45a8ff 660 __IO uint32_t *dmy_cfptr;
bogdanm 0:9b334a45a8ff 661 __IO uint32_t *dmy_cfdf0;
bogdanm 0:9b334a45a8ff 662 __IO uint32_t *dmy_cfdf1;
bogdanm 0:9b334a45a8ff 663 __IO uint32_t *dmy_cfpctr;
bogdanm 0:9b334a45a8ff 664 int retval = 0;
bogdanm 0:9b334a45a8ff 665
bogdanm 0:9b334a45a8ff 666 /* Wait to become channel communication mode */
bogdanm 0:9b334a45a8ff 667 dmy_sts = STS_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 668 while ((*dmy_sts & 0x07) != 0) {
bogdanm 0:9b334a45a8ff 669 __NOP();
bogdanm 0:9b334a45a8ff 670 }
bogdanm 0:9b334a45a8ff 671
bogdanm 0:9b334a45a8ff 672 /* send/receive FIFO buffer isn't empty */
bogdanm 0:9b334a45a8ff 673 dmy_cfsts = CFSTS_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 674 while ((*dmy_cfsts & 0x01) != 0x01) {
bogdanm 0:9b334a45a8ff 675 /* get format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
bogdanm 0:9b334a45a8ff 676 dmy_cfid = CFID_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 677 msg->format = (CANFormat)(*dmy_cfid >> 31);
bogdanm 0:9b334a45a8ff 678 msg->type = (CANType)(*dmy_cfid >> 30);
bogdanm 0:9b334a45a8ff 679 if (msg->format == CANStandard) {
bogdanm 0:9b334a45a8ff 680 msg->id = (*dmy_cfid & 0x07FF);
bogdanm 0:9b334a45a8ff 681 } else {
bogdanm 0:9b334a45a8ff 682 msg->id = ((*dmy_cfid >> 11) & 0x03FFFF);
bogdanm 0:9b334a45a8ff 683 }
bogdanm 0:9b334a45a8ff 684 /* get length */
bogdanm 0:9b334a45a8ff 685 dmy_cfptr = CFPTR_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 686 msg->len = (unsigned char)(*dmy_cfptr >> 28);
bogdanm 0:9b334a45a8ff 687 /* get data */
bogdanm 0:9b334a45a8ff 688 dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 689 memcpy(&msg->data[0], (void *)dmy_cfdf0, 4);
bogdanm 0:9b334a45a8ff 690 dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 691 memcpy(&msg->data[4], (void *)dmy_cfdf1, 4);
bogdanm 0:9b334a45a8ff 692 /* receive(next data) request */
bogdanm 0:9b334a45a8ff 693 dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 694 *dmy_cfpctr = 0xFF;
bogdanm 0:9b334a45a8ff 695 retval = 1;
bogdanm 0:9b334a45a8ff 696 }
bogdanm 0:9b334a45a8ff 697
bogdanm 0:9b334a45a8ff 698 return retval;
bogdanm 0:9b334a45a8ff 699 }
bogdanm 0:9b334a45a8ff 700
bogdanm 0:9b334a45a8ff 701 unsigned char can_rderror(can_t *obj) {
bogdanm 0:9b334a45a8ff 702 __IO uint32_t *dmy_sts;
bogdanm 0:9b334a45a8ff 703
bogdanm 0:9b334a45a8ff 704 dmy_sts = STS_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 705 return (unsigned char)((*dmy_sts >> 16) & 0xFF);
bogdanm 0:9b334a45a8ff 706 }
bogdanm 0:9b334a45a8ff 707
bogdanm 0:9b334a45a8ff 708 unsigned char can_tderror(can_t *obj) {
bogdanm 0:9b334a45a8ff 709 __IO uint32_t *dmy_sts;
bogdanm 0:9b334a45a8ff 710
bogdanm 0:9b334a45a8ff 711 dmy_sts = STS_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 712 return (unsigned char)((*dmy_sts >> 24) & 0xFF);
bogdanm 0:9b334a45a8ff 713 }
bogdanm 0:9b334a45a8ff 714
bogdanm 0:9b334a45a8ff 715 int can_mode(can_t *obj, CanMode mode) {
bogdanm 0:9b334a45a8ff 716 __IO uint32_t *dmy_ctr;
bogdanm 0:9b334a45a8ff 717 __IO uint32_t *dmy_sts;
bogdanm 0:9b334a45a8ff 718 __IO uint32_t *dmy_cfcc;
bogdanm 0:9b334a45a8ff 719 int ch_cnt;
bogdanm 0:9b334a45a8ff 720 can_t *tmp_obj;
bogdanm 0:9b334a45a8ff 721 tmp_obj = obj;
bogdanm 0:9b334a45a8ff 722 int retval = 1;
bogdanm 0:9b334a45a8ff 723
bogdanm 0:9b334a45a8ff 724 switch (mode) {
bogdanm 0:9b334a45a8ff 725 case MODE_RESET:
bogdanm 0:9b334a45a8ff 726 can_set_global_mode(GL_RESET);
bogdanm 0:9b334a45a8ff 727 can_set_channel_mode(obj->ch, CH_RESET);
bogdanm 0:9b334a45a8ff 728 for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
bogdanm 0:9b334a45a8ff 729 can_initialized[ch_cnt] = 0;
bogdanm 0:9b334a45a8ff 730 }
bogdanm 0:9b334a45a8ff 731 break;
bogdanm 0:9b334a45a8ff 732 case MODE_NORMAL:
bogdanm 0:9b334a45a8ff 733 can_set_global_mode(GL_OPE);
bogdanm 0:9b334a45a8ff 734 can_set_channel_mode(obj->ch, CH_COMM);
bogdanm 0:9b334a45a8ff 735 break;
bogdanm 0:9b334a45a8ff 736 case MODE_SILENT:
bogdanm 0:9b334a45a8ff 737 can_set_channel_mode(obj->ch, CH_HOLD);
bogdanm 0:9b334a45a8ff 738 /* set listen only mode, enable communication test mode */
bogdanm 0:9b334a45a8ff 739 dmy_ctr = CTR_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 740 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
bogdanm 0:9b334a45a8ff 741 can_set_channel_mode(obj->ch, CH_COMM);
bogdanm 0:9b334a45a8ff 742 break;
bogdanm 0:9b334a45a8ff 743 case MODE_TEST_LOCAL:
bogdanm 0:9b334a45a8ff 744 can_set_channel_mode(obj->ch, CH_HOLD);
bogdanm 0:9b334a45a8ff 745 /* set self test mode 0, enable communication test mode */
bogdanm 0:9b334a45a8ff 746 dmy_ctr = CTR_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 747 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x05000000);
bogdanm 0:9b334a45a8ff 748 can_set_channel_mode(obj->ch, CH_COMM);
bogdanm 0:9b334a45a8ff 749 break;
bogdanm 0:9b334a45a8ff 750 case MODE_TEST_GLOBAL:
bogdanm 0:9b334a45a8ff 751 /* set the channel between the communication test on channel 1 and channel 2 */
bogdanm 0:9b334a45a8ff 752 /* set Channel Hold mode */
bogdanm 0:9b334a45a8ff 753 for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
bogdanm 0:9b334a45a8ff 754 dmy_sts = STS_MATCH[tmp_obj->ch];
bogdanm 0:9b334a45a8ff 755 if ((*dmy_sts & 0x04) == 0x04) {
bogdanm 0:9b334a45a8ff 756 /* Channel Stop mode */
bogdanm 0:9b334a45a8ff 757 /* clear Channel Stop mode bit */
bogdanm 0:9b334a45a8ff 758 dmy_ctr = CTR_MATCH[tmp_obj->ch];
bogdanm 0:9b334a45a8ff 759 *dmy_ctr &= 0xFFFFFFFB;
bogdanm 0:9b334a45a8ff 760 can_set_channel_mode(tmp_obj->ch, CH_RESET);
bogdanm 0:9b334a45a8ff 761 }
bogdanm 0:9b334a45a8ff 762 can_set_channel_mode(tmp_obj->ch, CH_HOLD);
bogdanm 0:9b334a45a8ff 763 }
bogdanm 0:9b334a45a8ff 764 can_set_global_mode(GL_TEST);
bogdanm 0:9b334a45a8ff 765 /* enable communication test between channel1 and channel2 */
bogdanm 0:9b334a45a8ff 766 RSCAN0GTSTCFG = 0x06;
bogdanm 0:9b334a45a8ff 767 RSCAN0GTSTCTR = 0x01;
bogdanm 0:9b334a45a8ff 768 /* send and receive setting of channel1 and channel2 */
bogdanm 0:9b334a45a8ff 769 for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
bogdanm 0:9b334a45a8ff 770 can_reset_buffer(tmp_obj);
bogdanm 0:9b334a45a8ff 771 /* set global interrrupt */
bogdanm 0:9b334a45a8ff 772 /* THLEIE, MEIE and DEIE interrupts are disable */
bogdanm 0:9b334a45a8ff 773 RSCAN0GCTR &= 0xFFFFF8FF;
bogdanm 0:9b334a45a8ff 774 /* BLIE, OLIE, BORIE and BOEIE interrupts are disable */
bogdanm 0:9b334a45a8ff 775 /* TAIE, ALIE, EPIE, EWIE and BEIE interrupts are enable */
bogdanm 0:9b334a45a8ff 776 dmy_ctr = CTR_MATCH[tmp_obj->ch];
bogdanm 0:9b334a45a8ff 777 *dmy_ctr &= 0x00018700;
bogdanm 0:9b334a45a8ff 778 can_set_global_mode(GL_OPE);
bogdanm 0:9b334a45a8ff 779 can_set_channel_mode(tmp_obj->ch, CH_COMM);
bogdanm 0:9b334a45a8ff 780 /* Use send/receive FIFO buffer */
bogdanm 0:9b334a45a8ff 781 dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 782 *dmy_cfcc |= 0x01;
bogdanm 0:9b334a45a8ff 783 dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 784 *dmy_cfcc |= 0x01;
bogdanm 0:9b334a45a8ff 785 }
bogdanm 0:9b334a45a8ff 786 break;
bogdanm 0:9b334a45a8ff 787 case MODE_TEST_SILENT:
bogdanm 0:9b334a45a8ff 788 /* not supported */
bogdanm 0:9b334a45a8ff 789 /* fall through */
bogdanm 0:9b334a45a8ff 790 default:
bogdanm 0:9b334a45a8ff 791 retval = 0;
bogdanm 0:9b334a45a8ff 792 break;
bogdanm 0:9b334a45a8ff 793 }
bogdanm 0:9b334a45a8ff 794
bogdanm 0:9b334a45a8ff 795 return retval;
bogdanm 0:9b334a45a8ff 796 }
bogdanm 0:9b334a45a8ff 797
bogdanm 0:9b334a45a8ff 798 int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
bogdanm 0:9b334a45a8ff 799 int retval = 0;
bogdanm 0:9b334a45a8ff 800
bogdanm 0:9b334a45a8ff 801 if ((format == CANStandard) || (format == CANExtended)) {
bogdanm 0:9b334a45a8ff 802 if (((format == CANStandard) && (id <= 0x07FF)) || ((format == CANExtended) && (id <= 0x03FFFF))) {
bogdanm 0:9b334a45a8ff 803 /* set Global Reset mode and Channel Reset mode */
bogdanm 0:9b334a45a8ff 804 can_set_global_mode(GL_RESET);
bogdanm 0:9b334a45a8ff 805 can_set_channel_mode(obj->ch, CH_RESET);
bogdanm 0:9b334a45a8ff 806 /* enable receive rule table writing */
bogdanm 0:9b334a45a8ff 807 RSCAN0GAFLECTR = 0x00000100;
bogdanm 0:9b334a45a8ff 808 /* set the page number of receive rule table(page number = 0) */
bogdanm 0:9b334a45a8ff 809 RSCAN0GAFLECTR |= (obj->ch * 4);
bogdanm 0:9b334a45a8ff 810 /* set IDE format */
bogdanm 0:9b334a45a8ff 811 *dmy_gaflid = (format << 31);
bogdanm 0:9b334a45a8ff 812 if (format == CANExtended) {
bogdanm 0:9b334a45a8ff 813 /* set receive rule ID for bit28-11 */
bogdanm 0:9b334a45a8ff 814 *dmy_gaflid |= (id << 11);
bogdanm 0:9b334a45a8ff 815 } else {
bogdanm 0:9b334a45a8ff 816 /* set receive rule ID for bit10-0 */
bogdanm 0:9b334a45a8ff 817 *dmy_gaflid |= id;
bogdanm 0:9b334a45a8ff 818 }
bogdanm 0:9b334a45a8ff 819 /* set ID mask bit */
bogdanm 0:9b334a45a8ff 820 *dmy_gaflm = (0xC0000000 | mask);
bogdanm 0:9b334a45a8ff 821 /* disable receive rule table writing */
bogdanm 0:9b334a45a8ff 822 RSCAN0GAFLECTR &= 0xFFFFFEFF;
bogdanm 0:9b334a45a8ff 823 /* reconfigure channel which is already initialized */
bogdanm 0:9b334a45a8ff 824 can_reconfigure_channel();
bogdanm 0:9b334a45a8ff 825 retval = 1;
bogdanm 0:9b334a45a8ff 826 }
bogdanm 0:9b334a45a8ff 827 }
bogdanm 0:9b334a45a8ff 828
bogdanm 0:9b334a45a8ff 829 return retval;
bogdanm 0:9b334a45a8ff 830 }
bogdanm 0:9b334a45a8ff 831
bogdanm 0:9b334a45a8ff 832 void can_monitor(can_t *obj, int silent) {
bogdanm 0:9b334a45a8ff 833 __IO uint32_t *dmy_ctr;
bogdanm 0:9b334a45a8ff 834
bogdanm 0:9b334a45a8ff 835 /* set Channel Hold mode */
bogdanm 0:9b334a45a8ff 836 can_set_channel_mode(obj->ch, CH_HOLD);
bogdanm 0:9b334a45a8ff 837 if (silent) {
bogdanm 0:9b334a45a8ff 838 /* set listen only mode, enable communication test mode */
bogdanm 0:9b334a45a8ff 839 dmy_ctr = CTR_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 840 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
bogdanm 0:9b334a45a8ff 841 can_set_channel_mode(obj->ch, CH_COMM);
bogdanm 0:9b334a45a8ff 842 } else {
bogdanm 0:9b334a45a8ff 843 /* set normal test mode, disable communication test mode */
bogdanm 0:9b334a45a8ff 844 dmy_ctr = CTR_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 845 *dmy_ctr &= 0x00FFFFFF;
bogdanm 0:9b334a45a8ff 846 /* reset register */
bogdanm 0:9b334a45a8ff 847 can_reset_reg(obj);
bogdanm 0:9b334a45a8ff 848 /* reconfigure channel which is already initialized */
bogdanm 0:9b334a45a8ff 849 can_reconfigure_channel();
bogdanm 0:9b334a45a8ff 850 }
bogdanm 0:9b334a45a8ff 851 }
bogdanm 0:9b334a45a8ff 852
bogdanm 0:9b334a45a8ff 853 static void can_reset_reg(can_t *obj) {
bogdanm 0:9b334a45a8ff 854 __IO uint32_t *dmy_ctr;
bogdanm 0:9b334a45a8ff 855
bogdanm 0:9b334a45a8ff 856 /* time stamp source uses peripheral clock (pclk(P1_phi)/2), CAN clock uses clkc(P1_phi/2), */
bogdanm 0:9b334a45a8ff 857 /* mirror off, DLC not transfer, DLC check permit, transmit buffer priority, clock source not divided */
bogdanm 0:9b334a45a8ff 858 RSCAN0GCFG = 0x00000003;
bogdanm 0:9b334a45a8ff 859 /* set default frequency at 100k */
bogdanm 0:9b334a45a8ff 860 can_set_frequency(obj, 100000);
bogdanm 0:9b334a45a8ff 861 /* set receive rule */
bogdanm 0:9b334a45a8ff 862 can_reset_recv_rule(obj);
bogdanm 0:9b334a45a8ff 863 /* set buffer */
bogdanm 0:9b334a45a8ff 864 can_reset_buffer(obj);
bogdanm 0:9b334a45a8ff 865 /* set global interrrupt */
bogdanm 0:9b334a45a8ff 866 /* THLEIE, MEIE and DEIE interrupts are disable */
bogdanm 0:9b334a45a8ff 867 RSCAN0GCTR &= 0xFFFFF8FF;
bogdanm 0:9b334a45a8ff 868 /* ALIE, BLIE, OLIE, BORIE, BOEIE, EPIE, EWIE and BEIE interrupts are disable */
bogdanm 0:9b334a45a8ff 869 dmy_ctr = CTR_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 870 *dmy_ctr &= 0xFFFF00FF;
bogdanm 0:9b334a45a8ff 871 }
bogdanm 0:9b334a45a8ff 872
bogdanm 0:9b334a45a8ff 873 static void can_reset_recv_rule(can_t *obj) {
bogdanm 0:9b334a45a8ff 874 /* number of receive rules of each chanel = 64 */
bogdanm 0:9b334a45a8ff 875 RSCAN0GAFLCFG0 = 0x40404040;
bogdanm 0:9b334a45a8ff 876 RSCAN0GAFLCFG1 = 0x40000000;
bogdanm 0:9b334a45a8ff 877 /* enable receive rule table writing */
bogdanm 0:9b334a45a8ff 878 RSCAN0GAFLECTR = 0x00000100;
bogdanm 0:9b334a45a8ff 879 /* set the page number of receive rule table(ex: id ch = 1, page number = 4) */
bogdanm 0:9b334a45a8ff 880 RSCAN0GAFLECTR |= (obj->ch * 4);
bogdanm 0:9b334a45a8ff 881 /* set standard ID, data frame and receive rule ID */
bogdanm 0:9b334a45a8ff 882 *dmy_gaflid = 0x07FF;
bogdanm 0:9b334a45a8ff 883 /* IDE bit, RTR bit and ID bit(28-0) are not compared */
bogdanm 0:9b334a45a8ff 884 *dmy_gaflm = 0;
bogdanm 0:9b334a45a8ff 885 /* DLC check is 1 bytes, not use a receive buffer */
bogdanm 0:9b334a45a8ff 886 *dmy_gaflp0 = 0x10000000;
bogdanm 0:9b334a45a8ff 887 /* use a send/receive FIFO buffer(ex: if ch = 1, FIFO buffer number = 4 and bit = 12) */
bogdanm 0:9b334a45a8ff 888 *dmy_gaflp1 = (1 << ((obj->ch + 3) * 3));
bogdanm 0:9b334a45a8ff 889 /* disable receive rule table writing */
bogdanm 0:9b334a45a8ff 890 RSCAN0GAFLECTR &= 0xFFFFFEFF;
bogdanm 0:9b334a45a8ff 891 }
bogdanm 0:9b334a45a8ff 892
bogdanm 0:9b334a45a8ff 893 static void can_reset_buffer(can_t *obj) {
bogdanm 0:9b334a45a8ff 894 __IO uint32_t *dmy_rfcc;
bogdanm 0:9b334a45a8ff 895 __IO uint32_t *dmy_cfcc;
bogdanm 0:9b334a45a8ff 896 __IO uint32_t *dmy_txqcc;
bogdanm 0:9b334a45a8ff 897 __IO uint32_t *dmy_thlcc;
bogdanm 0:9b334a45a8ff 898 int cnt;
bogdanm 0:9b334a45a8ff 899
bogdanm 0:9b334a45a8ff 900 /* set linked send buffer number(ex: if ch = 1 and mode = send, buffer number = 16), interval timer is pclk/2 */
bogdanm 0:9b334a45a8ff 901 /* number of rows of send/receive FIFO buffer = 4 */
bogdanm 0:9b334a45a8ff 902 dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 903 *dmy_cfcc = 0x00011100; /* send/receive FIFO mode is send */
bogdanm 0:9b334a45a8ff 904 dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 905 *dmy_cfcc = 0x00001100; /* send/receive FIFO mode is receive */
bogdanm 0:9b334a45a8ff 906 /* receive buffer is not used */
bogdanm 0:9b334a45a8ff 907 RSCAN0RMNB = 0;
bogdanm 0:9b334a45a8ff 908 /* receive FIFO buffer is not used */
bogdanm 0:9b334a45a8ff 909 for (cnt = 0; cnt < 8; cnt++) {
bogdanm 0:9b334a45a8ff 910 dmy_rfcc = RFCC_MATCH[cnt];
bogdanm 0:9b334a45a8ff 911 *dmy_rfcc = 0;
bogdanm 0:9b334a45a8ff 912 }
bogdanm 0:9b334a45a8ff 913 /* send queue is not used */
bogdanm 0:9b334a45a8ff 914 dmy_txqcc = TXQCC_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 915 *dmy_txqcc = 0;
bogdanm 0:9b334a45a8ff 916 /* send history is not used */
bogdanm 0:9b334a45a8ff 917 dmy_thlcc = THLCC_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 918 *dmy_thlcc = 0;
bogdanm 0:9b334a45a8ff 919
bogdanm 0:9b334a45a8ff 920 /* CFTXIE and CFRXIE interrupts are enable */
bogdanm 0:9b334a45a8ff 921 dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
bogdanm 0:9b334a45a8ff 922 *dmy_cfcc |= 0x04;
bogdanm 0:9b334a45a8ff 923 dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
bogdanm 0:9b334a45a8ff 924 *dmy_cfcc |= 0x02;
bogdanm 0:9b334a45a8ff 925 /* TMIEp interrupt is disable */
bogdanm 0:9b334a45a8ff 926 RSCAN0TMIEC0 = 0x00000000;
bogdanm 0:9b334a45a8ff 927 RSCAN0TMIEC1 = 0x00000000;
bogdanm 0:9b334a45a8ff 928 RSCAN0TMIEC2 = 0x00000000;
bogdanm 0:9b334a45a8ff 929 }
bogdanm 0:9b334a45a8ff 930
bogdanm 0:9b334a45a8ff 931 static void can_reconfigure_channel(void) {
bogdanm 0:9b334a45a8ff 932 __IO uint32_t *dmy_cfcc;
bogdanm 0:9b334a45a8ff 933 int ch_cnt;
bogdanm 0:9b334a45a8ff 934
bogdanm 0:9b334a45a8ff 935 for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
bogdanm 0:9b334a45a8ff 936 if (can_initialized[ch_cnt] == 1) {
bogdanm 0:9b334a45a8ff 937 /* set Global Operation mode and Channel Communication mode */
bogdanm 0:9b334a45a8ff 938 can_set_global_mode(GL_OPE);
bogdanm 0:9b334a45a8ff 939 can_set_channel_mode(ch_cnt, CH_COMM);
bogdanm 0:9b334a45a8ff 940 /* Use send/receive FIFO buffer */
bogdanm 0:9b334a45a8ff 941 dmy_cfcc = CFCC_TBL[ch_cnt][CAN_SEND];
bogdanm 0:9b334a45a8ff 942 *dmy_cfcc |= 0x01;
bogdanm 0:9b334a45a8ff 943 dmy_cfcc = CFCC_TBL[ch_cnt][CAN_RECV];
bogdanm 0:9b334a45a8ff 944 *dmy_cfcc |= 0x01;
bogdanm 0:9b334a45a8ff 945 }
bogdanm 0:9b334a45a8ff 946 }
bogdanm 0:9b334a45a8ff 947 }
bogdanm 0:9b334a45a8ff 948
bogdanm 0:9b334a45a8ff 949 static void can_set_frequency(can_t *obj, int f) {
bogdanm 0:9b334a45a8ff 950 __IO uint32_t *dmy_cfg;
bogdanm 0:9b334a45a8ff 951 int oldfreq = 0;
bogdanm 0:9b334a45a8ff 952 int newfreq = 0;
bogdanm 0:9b334a45a8ff 953 uint32_t clkc_val;
bogdanm 0:9b334a45a8ff 954 uint8_t tmp_tq;
bogdanm 0:9b334a45a8ff 955 uint8_t tq = 0;
bogdanm 0:9b334a45a8ff 956 uint8_t tmp_brp;
bogdanm 0:9b334a45a8ff 957 uint8_t brp = 0;
bogdanm 0:9b334a45a8ff 958 uint8_t tseg1 = 0;
bogdanm 0:9b334a45a8ff 959 uint8_t tseg2 = 0;
bogdanm 0:9b334a45a8ff 960
bogdanm 0:9b334a45a8ff 961 /* set clkc */
bogdanm 0:9b334a45a8ff 962 if (RZ_A1_IsClockMode0() == false) {
bogdanm 0:9b334a45a8ff 963 clkc_val = CM1_RENESAS_RZ_A1_P1_CLK / 2;
bogdanm 0:9b334a45a8ff 964 } else {
bogdanm 0:9b334a45a8ff 965 clkc_val = CM0_RENESAS_RZ_A1_P1_CLK / 2;
bogdanm 0:9b334a45a8ff 966 }
bogdanm 0:9b334a45a8ff 967 /* calculate BRP bit and Choose max value of calculated frequency */
bogdanm 0:9b334a45a8ff 968 for (tmp_tq = 8; tmp_tq <= 25; tmp_tq++) {
bogdanm 0:9b334a45a8ff 969 /* f = fCAN / ((BRP+1) * Tq) */
bogdanm 0:9b334a45a8ff 970 /* BRP = (fCAN / (f * Tq)) - 1 */
bogdanm 0:9b334a45a8ff 971 tmp_brp = ((clkc_val / (f * tmp_tq)) - 1) + 1; // carry(decimal point is carry)
bogdanm 0:9b334a45a8ff 972 newfreq = clkc_val / ((tmp_brp + 1) * tmp_tq);
bogdanm 0:9b334a45a8ff 973 if (newfreq >= oldfreq) {
bogdanm 0:9b334a45a8ff 974 oldfreq = newfreq;
bogdanm 0:9b334a45a8ff 975 tq = tmp_tq;
bogdanm 0:9b334a45a8ff 976 brp = tmp_brp;
bogdanm 0:9b334a45a8ff 977 }
bogdanm 0:9b334a45a8ff 978 }
bogdanm 0:9b334a45a8ff 979 /* calculate TSEG1 bit and TSEG2 bit */
bogdanm 0:9b334a45a8ff 980 tseg1 = (tq - 1) * 0.666666667;
bogdanm 0:9b334a45a8ff 981 tseg2 = (tq - 1) - tseg1;
bogdanm 0:9b334a45a8ff 982 /* set RSCAN0CmCFG register */
bogdanm 0:9b334a45a8ff 983 dmy_cfg = CFG_MATCH[obj->ch];
bogdanm 0:9b334a45a8ff 984 *dmy_cfg = ((tseg2 - 1) << 20) | ((tseg1 - 1) << 16) | brp;
bogdanm 0:9b334a45a8ff 985 }
bogdanm 0:9b334a45a8ff 986
bogdanm 0:9b334a45a8ff 987 static void can_set_global_mode(int mode) {
bogdanm 0:9b334a45a8ff 988 /* set Global mode */
bogdanm 0:9b334a45a8ff 989 RSCAN0GCTR = ((RSCAN0GCTR & 0xFFFFFFFC) | mode);
bogdanm 0:9b334a45a8ff 990 /* Wait to cahnge into Global XXXX mode */
bogdanm 0:9b334a45a8ff 991 while ((RSCAN0GSTS & 0x07) != mode) {
bogdanm 0:9b334a45a8ff 992 __NOP();
bogdanm 0:9b334a45a8ff 993 }
bogdanm 0:9b334a45a8ff 994 }
bogdanm 0:9b334a45a8ff 995
bogdanm 0:9b334a45a8ff 996 static void can_set_channel_mode(uint32_t ch, int mode) {
bogdanm 0:9b334a45a8ff 997 __IO uint32_t *dmy_ctr;
bogdanm 0:9b334a45a8ff 998 __IO uint32_t *dmy_sts;
bogdanm 0:9b334a45a8ff 999
bogdanm 0:9b334a45a8ff 1000 /* set Channel mode */
bogdanm 0:9b334a45a8ff 1001 dmy_ctr = CTR_MATCH[ch];
bogdanm 0:9b334a45a8ff 1002 *dmy_ctr = ((*dmy_ctr & 0xFFFFFFFC) | mode);
bogdanm 0:9b334a45a8ff 1003 /* Wait to cahnge into Channel XXXX mode */
bogdanm 0:9b334a45a8ff 1004 dmy_sts = STS_MATCH[ch];
bogdanm 0:9b334a45a8ff 1005 while ((*dmy_sts & 0x07) != mode) {
bogdanm 0:9b334a45a8ff 1006 __NOP();
bogdanm 0:9b334a45a8ff 1007 }
bogdanm 0:9b334a45a8ff 1008 }
bogdanm 0:9b334a45a8ff 1009