t

Fork of mbed-dev by mbed official

Revision:
144:ef7eb2e8f9f7
Parent:
0:9b334a45a8ff
diff -r 423e1876dc07 -r ef7eb2e8f9f7 targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/can_api.c
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/can_api.c	Tue Aug 02 14:07:36 2016 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/can_api.c	Fri Sep 02 15:07:44 2016 +0100
@@ -1,1009 +1,1009 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <string.h>
-#include "mbed_assert.h"
-#include "can_api.h"
-#include "RZ_A1_Init.h"
-#include "cmsis.h"
-#include "pinmap.h"
-#include "rscan0_iodefine.h"
-#include "r_typedefs.h"
-#include "MBRZA1H.h"
-
-#define CAN_NUM         5
-#define CAN_SND_RCV     2
-#define IRQ_NUM         8
-
-static void can_rec_irq(uint32_t ch);
-static void can_trx_irq(uint32_t ch);
-static void can_err_irq(uint32_t ch, CanIrqType type);
-static void can0_rec_irq(void);
-static void can1_rec_irq(void);
-static void can2_rec_irq(void);
-static void can3_rec_irq(void);
-static void can4_rec_irq(void);
-static void can0_trx_irq(void);
-static void can1_trx_irq(void);
-static void can2_trx_irq(void);
-static void can3_trx_irq(void);
-static void can4_trx_irq(void);
-static void can0_err_warning_irq(void);
-static void can1_err_warning_irq(void);
-static void can2_err_warning_irq(void);
-static void can3_err_warning_irq(void);
-static void can4_err_warning_irq(void);
-static void can0_overrun_irq(void);
-static void can1_overrun_irq(void);
-static void can2_overrun_irq(void);
-static void can3_overrun_irq(void);
-static void can4_overrun_irq(void);
-static void can0_passive_irq(void);
-static void can1_passive_irq(void);
-static void can2_passive_irq(void);
-static void can3_passive_irq(void);
-static void can4_passive_irq(void);
-static void can0_arb_lost_irq(void);
-static void can1_arb_lost_irq(void);
-static void can2_arb_lost_irq(void);
-static void can3_arb_lost_irq(void);
-static void can4_arb_lost_irq(void);
-static void can0_bus_err_irq(void);
-static void can1_bus_err_irq(void);
-static void can2_bus_err_irq(void);
-static void can3_bus_err_irq(void);
-static void can4_bus_err_irq(void);
-static void can_reset_reg(can_t *obj);
-static void can_reset_recv_rule(can_t *obj);
-static void can_reset_buffer(can_t *obj);
-static void can_reconfigure_channel(void);
-static void can_set_frequency(can_t *obj, int f);
-static void can_set_global_mode(int mode);
-static void can_set_channel_mode(uint32_t ch, int mode);
-
-typedef enum {
-    CAN_SEND = 0,
-    CAN_RECV
-} CANfunc;
-
-typedef enum {
-    GL_OPE = 0,
-    GL_RESET,
-    GL_TEST
-} Globalmode;
-
-typedef enum {
-    CH_COMM = 0,
-    CH_RESET,
-    CH_HOLD
-} Channelmode;
-
-typedef struct {
-    IRQn_Type   int_num;    /* Interrupt number */
-    IRQHandler  handler;    /* Interrupt handler */
-} can_info_int_t;
-
-static can_irq_handler irq_handler;
-static uint32_t can_irq_id[CAN_NUM];
-static int can_initialized[CAN_NUM] = {0};
-
-static const PinMap PinMap_CAN_RD[] = {
-    {P7_8  , CAN_0, 4},
-    {P9_1  , CAN_0, 3},
-    {P1_4  , CAN_1, 3},
-    {P5_9  , CAN_1, 5},
-    {P7_11 , CAN_1, 4},
-    {P11_12, CAN_1, 1},
-    {P4_9  , CAN_2, 6},
-    {P6_4  , CAN_2, 3},
-    {P7_2  , CAN_2, 5},
-    {P2_12 , CAN_3, 5},
-    {P4_2  , CAN_3, 4},
-    {P1_5  , CAN_4, 3},
-    {P2_14 , CAN_4, 5},
-    {NC    , NC   , 0}
-};
-
-static const PinMap PinMap_CAN_TD[] = {
-    {P7_9  , CAN_0, 4},
-    {P9_0  , CAN_0, 3},
-    {P5_10 , CAN_1, 5},
-    {P7_10 , CAN_1, 4},
-    {P11_13, CAN_1, 1},
-    {P4_8  , CAN_2, 6},
-    {P6_5  , CAN_2, 3},
-    {P7_3  , CAN_2, 5},
-    {P2_13 , CAN_3, 5},
-    {P4_3  , CAN_3, 4},
-    {P4_11 , CAN_4, 6},
-    {P8_10 , CAN_4, 5},
-    {NC    , NC   , 0}
-};
-
-static __IO uint32_t *CTR_MATCH[] = {
-    &RSCAN0C0CTR,
-    &RSCAN0C1CTR,
-    &RSCAN0C2CTR,
-    &RSCAN0C3CTR,
-    &RSCAN0C4CTR,
-};
-
-static __IO uint32_t *CFG_MATCH[] = {
-    &RSCAN0C0CFG,
-    &RSCAN0C1CFG,
-    &RSCAN0C2CFG,
-    &RSCAN0C3CFG,
-    &RSCAN0C4CFG,
-};
-
-static __IO uint32_t *RFCC_MATCH[] = {
-    &RSCAN0RFCC0,
-    &RSCAN0RFCC1,
-    &RSCAN0RFCC2,
-    &RSCAN0RFCC3,
-    &RSCAN0RFCC4,
-    &RSCAN0RFCC5,
-    &RSCAN0RFCC6,
-    &RSCAN0RFCC7
-};
-
-static __IO uint32_t *TXQCC_MATCH[] = {
-    &RSCAN0TXQCC0,
-    &RSCAN0TXQCC1,
-    &RSCAN0TXQCC2,
-    &RSCAN0TXQCC3,
-    &RSCAN0TXQCC4,
-};
-
-static __IO uint32_t *THLCC_MATCH[] = {
-    &RSCAN0THLCC0,
-    &RSCAN0THLCC1,
-    &RSCAN0THLCC2,
-    &RSCAN0THLCC3,
-    &RSCAN0THLCC4,
-};
-
-static __IO uint32_t *STS_MATCH[] = {
-    &RSCAN0C0STS,
-    &RSCAN0C1STS,
-    &RSCAN0C2STS,
-    &RSCAN0C3STS,
-    &RSCAN0C4STS,
-};
-
-static __IO uint32_t *ERFL_MATCH[] = {
-    &RSCAN0C0ERFL,
-    &RSCAN0C1ERFL,
-    &RSCAN0C2ERFL,
-    &RSCAN0C3ERFL,
-    &RSCAN0C4ERFL,
-};
-
-static __IO uint32_t *CFCC_TBL[CAN_NUM][CAN_SND_RCV] = {
-    { &RSCAN0CFCC0 , &RSCAN0CFCC1  },
-    { &RSCAN0CFCC3 , &RSCAN0CFCC4  },
-    { &RSCAN0CFCC6 , &RSCAN0CFCC7  },
-    { &RSCAN0CFCC9 , &RSCAN0CFCC10 },
-    { &RSCAN0CFCC12, &RSCAN0CFCC13 }
-};
-
-static __IO uint32_t *CFSTS_TBL[CAN_NUM][CAN_SND_RCV] = {
-    { &RSCAN0CFSTS0 , &RSCAN0CFSTS1  },
-    { &RSCAN0CFSTS3 , &RSCAN0CFSTS4  },
-    { &RSCAN0CFSTS6 , &RSCAN0CFSTS7  },
-    { &RSCAN0CFSTS9 , &RSCAN0CFSTS10 },
-    { &RSCAN0CFSTS12, &RSCAN0CFSTS13 }
-};
-
-static __IO uint32_t *CFPCTR_TBL[CAN_NUM][CAN_SND_RCV] = {
-    { &RSCAN0CFPCTR0 , &RSCAN0CFPCTR1  },
-    { &RSCAN0CFPCTR3 , &RSCAN0CFPCTR4  },
-    { &RSCAN0CFPCTR6 , &RSCAN0CFPCTR7  },
-    { &RSCAN0CFPCTR9 , &RSCAN0CFPCTR10 },
-    { &RSCAN0CFPCTR12, &RSCAN0CFPCTR13 }
-};
-
-static __IO uint32_t *CFID_TBL[CAN_NUM][CAN_SND_RCV] = {
-    { &RSCAN0CFID0 , &RSCAN0CFID1  },
-    { &RSCAN0CFID3 , &RSCAN0CFID4  },
-    { &RSCAN0CFID6 , &RSCAN0CFID7  },
-    { &RSCAN0CFID9 , &RSCAN0CFID10 },
-    { &RSCAN0CFID12, &RSCAN0CFID13 }
-};
-
-static __IO uint32_t *CFPTR_TBL[CAN_NUM][CAN_SND_RCV] = {
-    { &RSCAN0CFPTR0 , &RSCAN0CFPTR1  },
-    { &RSCAN0CFPTR3 , &RSCAN0CFPTR4  },
-    { &RSCAN0CFPTR6 , &RSCAN0CFPTR7  },
-    { &RSCAN0CFPTR9 , &RSCAN0CFPTR10 },
-    { &RSCAN0CFPTR12, &RSCAN0CFPTR13 }
-};
-
-static __IO uint32_t *CFDF0_TBL[CAN_NUM][CAN_SND_RCV] = {
-    { &RSCAN0CFDF00 , &RSCAN0CFDF01  },
-    { &RSCAN0CFDF03 , &RSCAN0CFDF04  },
-    { &RSCAN0CFDF06 , &RSCAN0CFDF07  },
-    { &RSCAN0CFDF09 , &RSCAN0CFDF010 },
-    { &RSCAN0CFDF012, &RSCAN0CFDF013 }
-};
-
-static __IO uint32_t *CFDF1_TBL[CAN_NUM][CAN_SND_RCV] = {
-    { &RSCAN0CFDF10 , &RSCAN0CFDF11  },
-    { &RSCAN0CFDF13 , &RSCAN0CFDF14  },
-    { &RSCAN0CFDF16 , &RSCAN0CFDF17  },
-    { &RSCAN0CFDF19 , &RSCAN0CFDF110 },
-    { &RSCAN0CFDF112, &RSCAN0CFDF113 }
-};
-
-static const can_info_int_t can_int_info[CAN_NUM][IRQ_NUM] = 
-{
-    {   /* ch0 */
-        { INTRCAN0REC_IRQn, can0_rec_irq         }, /* RxIrq */
-        { INTRCAN0TRX_IRQn, can0_trx_irq         }, /* TxIrq */
-        { INTRCAN0ERR_IRQn, can0_err_warning_irq }, /* EwIrq */
-        { INTRCAN0ERR_IRQn, can0_overrun_irq     }, /* DoIrq */
-        { INTRCAN0ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
-        { INTRCAN0ERR_IRQn, can0_passive_irq     }, /* EpIrq */
-        { INTRCAN0ERR_IRQn, can0_arb_lost_irq    }, /* AlIrq */
-        { INTRCAN0ERR_IRQn, can0_bus_err_irq     }  /* BeIrq */
-    },
-    {   /* ch1 */
-        { INTRCAN1REC_IRQn, can1_rec_irq         }, /* RxIrq */
-        { INTRCAN1TRX_IRQn, can1_trx_irq         }, /* TxIrq */
-        { INTRCAN1ERR_IRQn, can1_err_warning_irq }, /* EwIrq */
-        { INTRCAN1ERR_IRQn, can1_overrun_irq     }, /* DoIrq */
-        { INTRCAN1ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
-        { INTRCAN1ERR_IRQn, can1_passive_irq     }, /* EpIrq */
-        { INTRCAN1ERR_IRQn, can1_arb_lost_irq    }, /* AlIrq */
-        { INTRCAN1ERR_IRQn, can1_bus_err_irq     }  /* BeIrq */
-    },
-    {   /* ch2 */
-        { INTRCAN2REC_IRQn, can2_rec_irq         }, /* RxIrq */
-        { INTRCAN2TRX_IRQn, can2_trx_irq         }, /* TxIrq */
-        { INTRCAN2ERR_IRQn, can2_err_warning_irq }, /* EwIrq */
-        { INTRCAN2ERR_IRQn, can2_overrun_irq     }, /* DoIrq */
-        { INTRCAN2ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
-        { INTRCAN2ERR_IRQn, can2_passive_irq     }, /* EpIrq */
-        { INTRCAN2ERR_IRQn, can2_arb_lost_irq    }, /* AlIrq */
-        { INTRCAN2ERR_IRQn, can2_bus_err_irq     }  /* BeIrq */
-    },
-    {   /* ch3 */
-        { INTRCAN3REC_IRQn, can3_rec_irq         }, /* RxIrq */
-        { INTRCAN3TRX_IRQn, can3_trx_irq         }, /* TxIrq */
-        { INTRCAN3ERR_IRQn, can3_err_warning_irq }, /* EwIrq */
-        { INTRCAN3ERR_IRQn, can3_overrun_irq     }, /* DoIrq */
-        { INTRCAN3ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
-        { INTRCAN3ERR_IRQn, can3_passive_irq     }, /* EpIrq */
-        { INTRCAN3ERR_IRQn, can3_arb_lost_irq    }, /* AlIrq */
-        { INTRCAN3ERR_IRQn, can3_bus_err_irq     }  /* BeIrq */
-    },
-    {   /* ch4 */
-        { INTRCAN4REC_IRQn, can4_rec_irq         }, /* RxIrq */
-        { INTRCAN4TRX_IRQn, can4_trx_irq         }, /* TxIrq */
-        { INTRCAN4ERR_IRQn, can4_err_warning_irq }, /* EwIrq */
-        { INTRCAN4ERR_IRQn, can4_overrun_irq     }, /* DoIrq */
-        { INTRCAN4ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
-        { INTRCAN4ERR_IRQn, can4_passive_irq     }, /* EpIrq */
-        { INTRCAN4ERR_IRQn, can4_arb_lost_irq    }, /* AlIrq */
-        { INTRCAN4ERR_IRQn, can4_bus_err_irq     }  /* BeIrq */
-    }
-};
-
-static __IO uint32_t *dmy_gaflid = &RSCAN0GAFLID0;
-static __IO uint32_t *dmy_gaflm  = &RSCAN0GAFLM0;
-static __IO uint32_t *dmy_gaflp0 = &RSCAN0GAFLP00;
-static __IO uint32_t *dmy_gaflp1 = &RSCAN0GAFLP10;
-
-void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
-    irq_handler = handler;
-    can_irq_id[obj->ch] = id;
-}
-
-void can_irq_free(can_t *obj) {
-    can_irq_id[obj->ch] = 0;
-}
-
-void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
-    __IO uint32_t *dmy_ctr;
-
-    /* Wake-up Irq is not supported */
-    if (type != IRQ_WAKEUP) {
-        if (enable) {
-            dmy_ctr = CTR_MATCH[obj->ch];
-            if (type == IRQ_ERROR) {
-                /* EWIE interrupts is enable */
-                *dmy_ctr |= 0x00000200;
-            } else if (type == IRQ_OVERRUN) {
-                /* OLIE interrupts is enable */
-                *dmy_ctr |= 0x00002000;
-            } else if (type == IRQ_PASSIVE) {
-                /* EPIE interrupts is enable */
-                *dmy_ctr |= 0x00000400;
-            } else if (type == IRQ_ARB) {
-                /* ALIE interrupts is enable */
-                *dmy_ctr |= 0x00008000;
-            } else if (type == IRQ_BUS) {
-                /* BEIE interrupts is enable */
-                *dmy_ctr |= 0x00000100;
-            }
-            InterruptHandlerRegister(can_int_info[obj->ch][type].int_num, can_int_info[obj->ch][type].handler);
-            GIC_SetPriority(can_int_info[obj->ch][type].int_num, 5);
-            GIC_EnableIRQ(can_int_info[obj->ch][type].int_num);
-        } else {
-            GIC_DisableIRQ(can_int_info[obj->ch][type].int_num);
-        }
-    }
-}
-
-static void can_rec_irq(uint32_t ch) {
-    __IO uint32_t *dmy_cfsts;
-
-    dmy_cfsts = CFSTS_TBL[ch][CAN_RECV];
-    *dmy_cfsts &= 0xFFFFFFF7;           // Clear CFRXIF
-
-    irq_handler(can_irq_id[ch], IRQ_RX);
-}
-
-static void can_trx_irq(uint32_t ch) {
-    __IO uint32_t *dmy_cfsts;
-
-    dmy_cfsts = CFSTS_TBL[ch][CAN_SEND];
-    *dmy_cfsts &= 0xFFFFFFEF;           // Clear CFTXIF
-
-    irq_handler(can_irq_id[ch], IRQ_TX);
-}
-
-static void can_err_irq(uint32_t ch, CanIrqType type) {
-    __IO uint32_t *dmy_erfl;
-    int val = 1;
-    
-    dmy_erfl = ERFL_MATCH[ch];
-    switch (type) {
-        case IRQ_ERROR:
-            *dmy_erfl &= 0xFFFFFFFD;    // Clear EWF
-            break;
-        case IRQ_OVERRUN:
-            *dmy_erfl &= 0xFFFFFFDF;    // Clear OVLF
-            break;
-        case IRQ_PASSIVE:
-            *dmy_erfl &= 0xFFFFFFFB;    // Clear EPF
-            break;
-        case IRQ_ARB:
-            *dmy_erfl &= 0xFFFFFF7F;    // Clear ALF
-            break;
-        case IRQ_BUS:
-            *dmy_erfl &= 0xFFFF00FF;    // Clear ADERRAB0ERRAB1ERRACERRAAERRAFERRASERR
-            *dmy_erfl &= 0xFFFFFFFE;    // Clear BEF
-            break;
-        case IRQ_WAKEUP:
-            /* not supported */
-            /* fall through */
-        default:
-            val = 0;
-            break;
-    }
-    if (val == 1) {
-        irq_handler(can_irq_id[ch], type);
-    }
-}
-
-static void can0_rec_irq(void) {
-    can_rec_irq(CAN_0);
-}
-
-static void can1_rec_irq(void) {
-    can_rec_irq(CAN_1);
-}
-
-static void can2_rec_irq(void) {
-    can_rec_irq(CAN_2);
-}
-
-static void can3_rec_irq(void) {
-    can_rec_irq(CAN_3);
-}
-
-static void can4_rec_irq(void) {
-    can_rec_irq(CAN_4);
-}
-
-static void can0_trx_irq(void) {
-    can_trx_irq(CAN_0);
-}
-
-static void can1_trx_irq(void) {
-    can_trx_irq(CAN_1);
-}
-
-static void can2_trx_irq(void) {
-    can_trx_irq(CAN_2);
-}
-
-static void can3_trx_irq(void) {
-    can_trx_irq(CAN_3);
-}
-
-static void can4_trx_irq(void) {
-    can_trx_irq(CAN_4);
-}
-
-static void can0_err_warning_irq(void) {
-    can_err_irq(CAN_0, IRQ_ERROR);
-}
-
-static void can1_err_warning_irq(void) {
-    can_err_irq(CAN_1, IRQ_ERROR);
-}
-
-static void can2_err_warning_irq(void) {
-    can_err_irq(CAN_2, IRQ_ERROR);
-}
-
-static void can3_err_warning_irq(void) {
-    can_err_irq(CAN_3, IRQ_ERROR);
-}
-
-static void can4_err_warning_irq(void) {
-    can_err_irq(CAN_4, IRQ_ERROR);
-}
-
-static void can0_overrun_irq(void) {
-    can_err_irq(CAN_0, IRQ_OVERRUN);
-}
-
-static void can1_overrun_irq(void) {
-    can_err_irq(CAN_1, IRQ_OVERRUN);
-}
-
-static void can2_overrun_irq(void) {
-    can_err_irq(CAN_2, IRQ_OVERRUN);
-}
-
-static void can3_overrun_irq(void) {
-    can_err_irq(CAN_3, IRQ_OVERRUN);
-}
-
-static void can4_overrun_irq(void) {
-    can_err_irq(CAN_4, IRQ_OVERRUN);
-}
-
-static void can0_passive_irq(void) {
-    can_err_irq(CAN_0, IRQ_PASSIVE);
-}
-
-static void can1_passive_irq(void) {
-    can_err_irq(CAN_1, IRQ_PASSIVE);
-}
-
-static void can2_passive_irq(void) {
-    can_err_irq(CAN_2, IRQ_PASSIVE);
-}
-
-static void can3_passive_irq(void) {
-    can_err_irq(CAN_3, IRQ_PASSIVE);
-}
-
-static void can4_passive_irq(void) {
-    can_err_irq(CAN_4, IRQ_PASSIVE);
-}
-
-static void can0_arb_lost_irq(void) {
-    can_err_irq(CAN_0, IRQ_ARB);
-}
-
-static void can1_arb_lost_irq(void) {
-    can_err_irq(CAN_1, IRQ_ARB);
-}
-
-static void can2_arb_lost_irq(void) {
-    can_err_irq(CAN_2, IRQ_ARB);
-}
-
-static void can3_arb_lost_irq(void) {
-    can_err_irq(CAN_3, IRQ_ARB);
-}
-
-static void can4_arb_lost_irq(void) {
-    can_err_irq(CAN_4, IRQ_ARB);
-}
-
-static void can0_bus_err_irq(void) {
-    can_err_irq(CAN_0, IRQ_BUS);
-}
-
-static void can1_bus_err_irq(void) {
-    can_err_irq(CAN_1, IRQ_BUS);
-}
-
-static void can2_bus_err_irq(void) {
-    can_err_irq(CAN_2, IRQ_BUS);
-}
-
-static void can3_bus_err_irq(void) {
-    can_err_irq(CAN_3, IRQ_BUS);
-}
-
-static void can4_bus_err_irq(void) {
-    can_err_irq(CAN_4, IRQ_BUS);
-}
-
-void can_init(can_t *obj, PinName rd, PinName td) {
-    __IO uint32_t *dmy_ctr;
-
-    /* determine the CAN to use */
-    uint32_t can_rx = pinmap_peripheral(rd, PinMap_CAN_RD);
-    uint32_t can_tx = pinmap_peripheral(td, PinMap_CAN_TD);
-    obj->ch = pinmap_merge(can_tx, can_rx);
-    MBED_ASSERT((int)obj->ch != NC);
-
-    /* enable CAN clock */
-    CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP32);
-    /* Has CAN RAM initialisation completed ? */
-    while ((RSCAN0GSTS & 0x08) == 0x08) {
-        __NOP();
-    }
-    /* clear Global Stop mode bit */
-    RSCAN0GCTR &= 0xFFFFFFFB;
-    /* clear Channel Stop mode bit */
-    dmy_ctr = CTR_MATCH[obj->ch];
-    *dmy_ctr &= 0xFFFFFFFB;
-    /* Enter global reset mode */
-    can_set_global_mode(GL_RESET);
-    /* Enter channel reset mode */
-    can_set_channel_mode(obj->ch, CH_RESET);
-    /* reset register */
-    can_reset_reg(obj);
-
-    can_initialized[obj->ch] = 1;
-    /* reconfigure channel which is already initialized */
-    can_reconfigure_channel();
-    
-    /* pin out the can pins */
-    pinmap_pinout(rd, PinMap_CAN_RD);
-    pinmap_pinout(td, PinMap_CAN_TD);
-}
-
-void can_free(can_t *obj) {
-    /* disable CAN clock */
-    CPGSTBCR3 |= CPG_STBCR3_BIT_MSTP32;
-}
-
-int can_frequency(can_t *obj, int f) {
-    int retval = 0;
-    
-    if (f <= 1000000) {
-        /* less than 1Mhz */
-        /* set Channel Reset mode */
-        can_set_channel_mode(obj->ch, CH_RESET);
-        can_set_frequency(obj, f);
-        /* set Channel Communication mode */
-        can_set_channel_mode(obj->ch, CH_COMM);
-        retval = 1;
-    }
-
-    return retval;
-}
-
-void can_reset(can_t *obj) {
-    /* Enter global reset mode */
-    can_set_global_mode(GL_RESET);
-    /* Enter channel reset mode */
-    can_set_channel_mode(obj->ch, CH_RESET);
-    /* reset register */
-    can_reset_reg(obj);
-    /* reconfigure channel which is already initialized */
-    can_reconfigure_channel();
-}
-
-int can_write(can_t *obj, CAN_Message msg, int cc) {
-    __IO uint32_t *dmy_sts;
-    __IO uint32_t *dmy_cfsts;
-    __IO uint32_t *dmy_cfid;
-    __IO uint32_t *dmy_cfptr;
-    __IO uint32_t *dmy_cfdf0;
-    __IO uint32_t *dmy_cfdf1;
-    __IO uint32_t *dmy_cfpctr;
-    int retval = 0;
-
-    /* Wait to become channel communication mode */
-    dmy_sts = STS_MATCH[obj->ch];
-    while ((*dmy_sts & 0x07) != 0) {
-        __NOP();
-    }
-    
-    if (((msg.format == CANStandard) && (msg.id <= 0x07FF)) || ((msg.format == CANExtended) && (msg.id <= 0x03FFFF))) {
-        /* send/receive FIFO buffer isn't full */
-        dmy_cfsts = CFSTS_TBL[obj->ch][CAN_SEND];
-        if ((*dmy_cfsts & 0x02) != 0x02) {
-            /* set format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
-            dmy_cfid = CFID_TBL[obj->ch][CAN_SEND];
-            *dmy_cfid = ((msg.format << 31) | (msg.type << 30));
-            if (msg.format == CANStandard) {
-                *dmy_cfid |= (msg.id & 0x07FF);
-            } else {
-                *dmy_cfid |= ((msg.id & 0x03FFFF) << 11);
-            }
-            /* set length */
-            dmy_cfptr = CFPTR_TBL[obj->ch][CAN_SEND];
-            *dmy_cfptr = msg.len << 28;
-            /* set data */
-            dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_SEND];
-            memcpy((void *)dmy_cfdf0, &msg.data[0], 4);
-            dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_SEND];
-            memcpy((void *)dmy_cfdf1, &msg.data[4], 4);
-            /* send request */
-            dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_SEND];
-            *dmy_cfpctr = 0xFF;
-            retval = 1;
-        }
-    }
-    
-    return retval;
-}
-
-int can_read(can_t *obj, CAN_Message *msg, int handle) {
-    __IO uint32_t *dmy_sts;
-    __IO uint32_t *dmy_cfsts;
-    __IO uint32_t *dmy_cfid;
-    __IO uint32_t *dmy_cfptr;
-    __IO uint32_t *dmy_cfdf0;
-    __IO uint32_t *dmy_cfdf1;
-    __IO uint32_t *dmy_cfpctr;
-    int retval = 0;
-
-    /* Wait to become channel communication mode */
-    dmy_sts = STS_MATCH[obj->ch];
-    while ((*dmy_sts & 0x07) != 0) {
-        __NOP();
-    }
-    
-    /* send/receive FIFO buffer isn't empty */
-    dmy_cfsts = CFSTS_TBL[obj->ch][CAN_RECV];
-    while ((*dmy_cfsts & 0x01) != 0x01) {
-        /* get format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
-        dmy_cfid = CFID_TBL[obj->ch][CAN_RECV];
-        msg->format = (CANFormat)(*dmy_cfid >> 31);
-        msg->type = (CANType)(*dmy_cfid >> 30);
-        if (msg->format == CANStandard) {
-            msg->id = (*dmy_cfid & 0x07FF);
-        } else {
-            msg->id = ((*dmy_cfid >> 11) & 0x03FFFF);
-        }
-        /* get length */
-        dmy_cfptr = CFPTR_TBL[obj->ch][CAN_RECV];
-        msg->len = (unsigned char)(*dmy_cfptr >> 28);
-        /* get data */
-        dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_RECV];
-        memcpy(&msg->data[0], (void *)dmy_cfdf0, 4);
-        dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_RECV];
-        memcpy(&msg->data[4], (void *)dmy_cfdf1, 4);
-        /* receive(next data) request */
-        dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_RECV];
-        *dmy_cfpctr = 0xFF;
-        retval = 1;
-    }
-    
-    return retval;
-}
-
-unsigned char can_rderror(can_t *obj) {
-    __IO uint32_t *dmy_sts;
-    
-    dmy_sts = STS_MATCH[obj->ch];
-    return (unsigned char)((*dmy_sts >> 16) & 0xFF);
-}
-
-unsigned char can_tderror(can_t *obj) {
-    __IO uint32_t *dmy_sts;
-    
-    dmy_sts = STS_MATCH[obj->ch];
-    return (unsigned char)((*dmy_sts >> 24) & 0xFF);
-}
-
-int can_mode(can_t *obj, CanMode mode) {
-    __IO uint32_t *dmy_ctr;
-    __IO uint32_t *dmy_sts;
-    __IO uint32_t *dmy_cfcc;
-    int ch_cnt;
-    can_t *tmp_obj;
-    tmp_obj = obj;
-    int retval = 1;
-    
-    switch (mode) {
-        case MODE_RESET:
-            can_set_global_mode(GL_RESET);
-            can_set_channel_mode(obj->ch, CH_RESET);
-            for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
-                can_initialized[ch_cnt] = 0;
-            }
-            break;
-        case MODE_NORMAL:
-            can_set_global_mode(GL_OPE);
-            can_set_channel_mode(obj->ch, CH_COMM);
-            break;
-        case MODE_SILENT:
-            can_set_channel_mode(obj->ch, CH_HOLD);
-            /* set listen only mode, enable communication test mode */
-            dmy_ctr = CTR_MATCH[obj->ch];
-            *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
-            can_set_channel_mode(obj->ch, CH_COMM);
-            break;
-        case MODE_TEST_LOCAL:
-            can_set_channel_mode(obj->ch, CH_HOLD);
-            /* set self test mode 0, enable communication test mode */
-            dmy_ctr = CTR_MATCH[obj->ch];
-            *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x05000000);
-            can_set_channel_mode(obj->ch, CH_COMM);
-            break;
-        case MODE_TEST_GLOBAL:
-            /* set the channel between the communication test on channel 1 and channel 2 */
-            /* set Channel Hold mode */
-            for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
-                dmy_sts = STS_MATCH[tmp_obj->ch];
-                if ((*dmy_sts & 0x04) == 0x04) {
-                    /* Channel Stop mode */
-                    /* clear Channel Stop mode bit */
-                    dmy_ctr = CTR_MATCH[tmp_obj->ch];
-                    *dmy_ctr &= 0xFFFFFFFB;
-                    can_set_channel_mode(tmp_obj->ch, CH_RESET);
-                }
-                can_set_channel_mode(tmp_obj->ch, CH_HOLD);
-            }
-            can_set_global_mode(GL_TEST);
-            /* enable communication test between channel1 and channel2 */
-            RSCAN0GTSTCFG = 0x06;
-            RSCAN0GTSTCTR = 0x01;
-            /* send and receive setting of channel1 and channel2 */
-            for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
-                can_reset_buffer(tmp_obj);
-                /* set global interrrupt */
-                /* THLEIE, MEIE and DEIE interrupts are disable */
-                RSCAN0GCTR &= 0xFFFFF8FF;
-                /* BLIE, OLIE, BORIE and BOEIE interrupts are disable */
-                /* TAIE, ALIE, EPIE, EWIE and BEIE interrupts are enable */
-                dmy_ctr = CTR_MATCH[tmp_obj->ch];
-                *dmy_ctr &= 0x00018700;
-                can_set_global_mode(GL_OPE);
-                can_set_channel_mode(tmp_obj->ch, CH_COMM);
-                /* Use send/receive FIFO buffer */
-                dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_SEND];
-                *dmy_cfcc |= 0x01;
-                dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_RECV];
-                *dmy_cfcc |= 0x01;
-            }
-            break;
-        case MODE_TEST_SILENT:
-            /* not supported */
-            /* fall through */
-        default:
-            retval = 0;
-            break;
-    }
-    
-    return retval;
-}
-
-int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
-    int retval = 0;
-    
-    if ((format == CANStandard) || (format == CANExtended)) {
-        if (((format == CANStandard) && (id <= 0x07FF)) || ((format == CANExtended) && (id <= 0x03FFFF))) {
-            /* set Global Reset mode and Channel Reset mode */
-            can_set_global_mode(GL_RESET);
-            can_set_channel_mode(obj->ch, CH_RESET);
-            /* enable receive rule table writing */
-            RSCAN0GAFLECTR = 0x00000100;
-            /* set the page number of receive rule table(page number = 0) */
-            RSCAN0GAFLECTR |= (obj->ch * 4);
-            /* set IDE format */
-            *dmy_gaflid = (format << 31);
-            if (format == CANExtended) {
-                /* set receive rule ID for bit28-11 */
-                *dmy_gaflid |= (id << 11);
-            } else {
-                /* set receive rule ID for bit10-0 */
-                *dmy_gaflid |= id;
-            }
-            /* set ID mask bit */
-            *dmy_gaflm = (0xC0000000 | mask);
-            /* disable receive rule table writing */
-            RSCAN0GAFLECTR &= 0xFFFFFEFF;
-            /* reconfigure channel which is already initialized */
-            can_reconfigure_channel();
-            retval = 1;
-        }
-    }
-    
-    return retval;
-}
-
-void can_monitor(can_t *obj, int silent) {
-    __IO uint32_t *dmy_ctr;
-
-    /* set Channel Hold mode */
-    can_set_channel_mode(obj->ch, CH_HOLD);
-    if (silent) {
-        /* set listen only mode, enable communication test mode */
-        dmy_ctr = CTR_MATCH[obj->ch];
-        *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
-        can_set_channel_mode(obj->ch, CH_COMM);
-    } else {
-        /* set normal test mode, disable communication test mode */
-        dmy_ctr = CTR_MATCH[obj->ch];
-        *dmy_ctr &= 0x00FFFFFF;
-        /* reset register */
-        can_reset_reg(obj);
-        /* reconfigure channel which is already initialized */
-        can_reconfigure_channel();
-    }
-}
-
-static void can_reset_reg(can_t *obj) {
-    __IO uint32_t *dmy_ctr;
-
-    /* time stamp source uses peripheral clock (pclk(P1_phi)/2), CAN clock uses clkc(P1_phi/2),           */
-    /* mirror off, DLC not transfer, DLC check permit, transmit buffer priority, clock source not divided */
-    RSCAN0GCFG = 0x00000003;
-    /* set default frequency at 100k */
-    can_set_frequency(obj, 100000);
-    /* set receive rule */
-    can_reset_recv_rule(obj);
-    /* set buffer */
-    can_reset_buffer(obj);
-    /* set global interrrupt */
-    /* THLEIE, MEIE and DEIE interrupts are disable */
-    RSCAN0GCTR &= 0xFFFFF8FF;
-    /* ALIE, BLIE, OLIE, BORIE, BOEIE, EPIE, EWIE and BEIE interrupts are disable */
-    dmy_ctr = CTR_MATCH[obj->ch];
-    *dmy_ctr &= 0xFFFF00FF;
-}
-
-static void can_reset_recv_rule(can_t *obj) {
-    /* number of receive rules of each chanel = 64 */
-    RSCAN0GAFLCFG0 = 0x40404040;
-    RSCAN0GAFLCFG1 = 0x40000000;
-    /* enable receive rule table writing */
-    RSCAN0GAFLECTR = 0x00000100;
-    /* set the page number of receive rule table(ex: id ch = 1, page number = 4) */
-    RSCAN0GAFLECTR |= (obj->ch * 4);
-    /* set standard ID, data frame and receive rule ID */
-    *dmy_gaflid = 0x07FF;
-    /* IDE bit, RTR bit and ID bit(28-0) are not compared */
-    *dmy_gaflm = 0;
-    /* DLC check is 1 bytes, not use a receive buffer */
-    *dmy_gaflp0 = 0x10000000;
-    /* use a send/receive FIFO buffer(ex: if ch = 1, FIFO buffer number = 4 and bit = 12) */
-    *dmy_gaflp1 = (1 << ((obj->ch + 3) * 3));
-    /* disable receive rule table writing */
-    RSCAN0GAFLECTR &= 0xFFFFFEFF;
-}
-
-static void can_reset_buffer(can_t *obj) {
-    __IO uint32_t *dmy_rfcc;
-    __IO uint32_t *dmy_cfcc;
-    __IO uint32_t *dmy_txqcc;
-    __IO uint32_t *dmy_thlcc;
-    int cnt;
-    
-    /* set linked send buffer number(ex: if ch = 1 and mode = send, buffer number = 16), interval timer is pclk/2 */
-    /* number of rows of send/receive FIFO buffer = 4 */
-    dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
-    *dmy_cfcc = 0x00011100;                 /* send/receive FIFO mode is send */
-    dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
-    *dmy_cfcc = 0x00001100;                 /* send/receive FIFO mode is receive */
-    /* receive buffer is not used */
-    RSCAN0RMNB = 0;
-    /* receive FIFO buffer is not used */
-    for (cnt = 0; cnt < 8; cnt++) {
-        dmy_rfcc = RFCC_MATCH[cnt];
-        *dmy_rfcc = 0;
-    }
-    /* send queue is not used */
-    dmy_txqcc = TXQCC_MATCH[obj->ch];
-    *dmy_txqcc = 0;
-    /* send history is not used */
-    dmy_thlcc = THLCC_MATCH[obj->ch];
-    *dmy_thlcc = 0;
-
-    /* CFTXIE and CFRXIE interrupts are enable */
-    dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
-    *dmy_cfcc |= 0x04;
-    dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
-    *dmy_cfcc |= 0x02;
-    /* TMIEp interrupt is disable */
-    RSCAN0TMIEC0 = 0x00000000;
-    RSCAN0TMIEC1 = 0x00000000;
-    RSCAN0TMIEC2 = 0x00000000;
-}
-
-static void can_reconfigure_channel(void) {
-    __IO uint32_t *dmy_cfcc;
-    int ch_cnt;
-
-    for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
-        if (can_initialized[ch_cnt] == 1) {
-            /* set Global Operation mode and Channel Communication mode */
-            can_set_global_mode(GL_OPE);
-            can_set_channel_mode(ch_cnt, CH_COMM);
-            /* Use send/receive FIFO buffer */
-            dmy_cfcc = CFCC_TBL[ch_cnt][CAN_SEND];
-            *dmy_cfcc |= 0x01;
-            dmy_cfcc = CFCC_TBL[ch_cnt][CAN_RECV];
-            *dmy_cfcc |= 0x01;
-        }
-    }
-}
-
-static void can_set_frequency(can_t *obj, int f) {
-    __IO uint32_t *dmy_cfg;
-    int oldfreq = 0;
-    int newfreq = 0;
-    uint32_t  clkc_val;
-    uint8_t tmp_tq;
-    uint8_t tq = 0;
-    uint8_t tmp_brp;
-    uint8_t brp = 0;
-    uint8_t tseg1 = 0;
-    uint8_t tseg2 = 0;
-    
-    /* set clkc */
-    if (RZ_A1_IsClockMode0() == false) {
-        clkc_val = CM1_RENESAS_RZ_A1_P1_CLK / 2;
-    } else {
-        clkc_val = CM0_RENESAS_RZ_A1_P1_CLK / 2;
-    }
-    /* calculate BRP bit and Choose max value of calculated frequency */
-    for (tmp_tq = 8; tmp_tq <= 25; tmp_tq++) {
-        /* f = fCAN / ((BRP+1) * Tq) */
-        /* BRP = (fCAN / (f * Tq)) - 1 */
-        tmp_brp = ((clkc_val / (f * tmp_tq)) - 1) + 1;   // carry(decimal point is carry)
-        newfreq = clkc_val / ((tmp_brp + 1) * tmp_tq);
-        if (newfreq >= oldfreq) {
-            oldfreq  = newfreq;
-            tq       = tmp_tq;
-            brp      = tmp_brp;
-        }
-    }
-    /* calculate TSEG1 bit and TSEG2 bit */
-    tseg1 = (tq - 1) * 0.666666667;
-    tseg2 = (tq - 1) - tseg1;
-    /* set RSCAN0CmCFG register */
-    dmy_cfg = CFG_MATCH[obj->ch];
-    *dmy_cfg = ((tseg2 - 1) << 20) | ((tseg1 - 1) << 16) | brp;
-}
-
-static void can_set_global_mode(int mode) {
-    /* set Global mode */
-    RSCAN0GCTR = ((RSCAN0GCTR & 0xFFFFFFFC) | mode);
-    /* Wait to cahnge into Global XXXX mode */
-    while ((RSCAN0GSTS & 0x07) != mode) {
-        __NOP();
-    }
-}
-
-static void can_set_channel_mode(uint32_t ch, int mode) {
-    __IO uint32_t *dmy_ctr;
-    __IO uint32_t *dmy_sts;
-
-    /* set Channel mode */
-    dmy_ctr = CTR_MATCH[ch];
-    *dmy_ctr = ((*dmy_ctr & 0xFFFFFFFC) | mode);
-    /* Wait to cahnge into Channel XXXX mode */
-    dmy_sts = STS_MATCH[ch];
-    while ((*dmy_sts & 0x07) != mode) {
-        __NOP();
-    }
-}
-
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <string.h>
+#include "mbed_assert.h"
+#include "can_api.h"
+#include "RZ_A1_Init.h"
+#include "cmsis.h"
+#include "pinmap.h"
+#include "rscan0_iodefine.h"
+#include "r_typedefs.h"
+#include "MBRZA1H.h"
+
+#define CAN_NUM         5
+#define CAN_SND_RCV     2
+#define IRQ_NUM         8
+
+static void can_rec_irq(uint32_t ch);
+static void can_trx_irq(uint32_t ch);
+static void can_err_irq(uint32_t ch, CanIrqType type);
+static void can0_rec_irq(void);
+static void can1_rec_irq(void);
+static void can2_rec_irq(void);
+static void can3_rec_irq(void);
+static void can4_rec_irq(void);
+static void can0_trx_irq(void);
+static void can1_trx_irq(void);
+static void can2_trx_irq(void);
+static void can3_trx_irq(void);
+static void can4_trx_irq(void);
+static void can0_err_warning_irq(void);
+static void can1_err_warning_irq(void);
+static void can2_err_warning_irq(void);
+static void can3_err_warning_irq(void);
+static void can4_err_warning_irq(void);
+static void can0_overrun_irq(void);
+static void can1_overrun_irq(void);
+static void can2_overrun_irq(void);
+static void can3_overrun_irq(void);
+static void can4_overrun_irq(void);
+static void can0_passive_irq(void);
+static void can1_passive_irq(void);
+static void can2_passive_irq(void);
+static void can3_passive_irq(void);
+static void can4_passive_irq(void);
+static void can0_arb_lost_irq(void);
+static void can1_arb_lost_irq(void);
+static void can2_arb_lost_irq(void);
+static void can3_arb_lost_irq(void);
+static void can4_arb_lost_irq(void);
+static void can0_bus_err_irq(void);
+static void can1_bus_err_irq(void);
+static void can2_bus_err_irq(void);
+static void can3_bus_err_irq(void);
+static void can4_bus_err_irq(void);
+static void can_reset_reg(can_t *obj);
+static void can_reset_recv_rule(can_t *obj);
+static void can_reset_buffer(can_t *obj);
+static void can_reconfigure_channel(void);
+static void can_set_frequency(can_t *obj, int f);
+static void can_set_global_mode(int mode);
+static void can_set_channel_mode(uint32_t ch, int mode);
+
+typedef enum {
+    CAN_SEND = 0,
+    CAN_RECV
+} CANfunc;
+
+typedef enum {
+    GL_OPE = 0,
+    GL_RESET,
+    GL_TEST
+} Globalmode;
+
+typedef enum {
+    CH_COMM = 0,
+    CH_RESET,
+    CH_HOLD
+} Channelmode;
+
+typedef struct {
+    IRQn_Type   int_num;    /* Interrupt number */
+    IRQHandler  handler;    /* Interrupt handler */
+} can_info_int_t;
+
+static can_irq_handler irq_handler;
+static uint32_t can_irq_id[CAN_NUM];
+static int can_initialized[CAN_NUM] = {0};
+
+static const PinMap PinMap_CAN_RD[] = {
+    {P7_8  , CAN_0, 4},
+    {P9_1  , CAN_0, 3},
+    {P1_4  , CAN_1, 3},
+    {P5_9  , CAN_1, 5},
+    {P7_11 , CAN_1, 4},
+    {P11_12, CAN_1, 1},
+    {P4_9  , CAN_2, 6},
+    {P6_4  , CAN_2, 3},
+    {P7_2  , CAN_2, 5},
+    {P2_12 , CAN_3, 5},
+    {P4_2  , CAN_3, 4},
+    {P1_5  , CAN_4, 3},
+    {P2_14 , CAN_4, 5},
+    {NC    , NC   , 0}
+};
+
+static const PinMap PinMap_CAN_TD[] = {
+    {P7_9  , CAN_0, 4},
+    {P9_0  , CAN_0, 3},
+    {P5_10 , CAN_1, 5},
+    {P7_10 , CAN_1, 4},
+    {P11_13, CAN_1, 1},
+    {P4_8  , CAN_2, 6},
+    {P6_5  , CAN_2, 3},
+    {P7_3  , CAN_2, 5},
+    {P2_13 , CAN_3, 5},
+    {P4_3  , CAN_3, 4},
+    {P4_11 , CAN_4, 6},
+    {P8_10 , CAN_4, 5},
+    {NC    , NC   , 0}
+};
+
+static __IO uint32_t *CTR_MATCH[] = {
+    &RSCAN0C0CTR,
+    &RSCAN0C1CTR,
+    &RSCAN0C2CTR,
+    &RSCAN0C3CTR,
+    &RSCAN0C4CTR,
+};
+
+static __IO uint32_t *CFG_MATCH[] = {
+    &RSCAN0C0CFG,
+    &RSCAN0C1CFG,
+    &RSCAN0C2CFG,
+    &RSCAN0C3CFG,
+    &RSCAN0C4CFG,
+};
+
+static __IO uint32_t *RFCC_MATCH[] = {
+    &RSCAN0RFCC0,
+    &RSCAN0RFCC1,
+    &RSCAN0RFCC2,
+    &RSCAN0RFCC3,
+    &RSCAN0RFCC4,
+    &RSCAN0RFCC5,
+    &RSCAN0RFCC6,
+    &RSCAN0RFCC7
+};
+
+static __IO uint32_t *TXQCC_MATCH[] = {
+    &RSCAN0TXQCC0,
+    &RSCAN0TXQCC1,
+    &RSCAN0TXQCC2,
+    &RSCAN0TXQCC3,
+    &RSCAN0TXQCC4,
+};
+
+static __IO uint32_t *THLCC_MATCH[] = {
+    &RSCAN0THLCC0,
+    &RSCAN0THLCC1,
+    &RSCAN0THLCC2,
+    &RSCAN0THLCC3,
+    &RSCAN0THLCC4,
+};
+
+static __IO uint32_t *STS_MATCH[] = {
+    &RSCAN0C0STS,
+    &RSCAN0C1STS,
+    &RSCAN0C2STS,
+    &RSCAN0C3STS,
+    &RSCAN0C4STS,
+};
+
+static __IO uint32_t *ERFL_MATCH[] = {
+    &RSCAN0C0ERFL,
+    &RSCAN0C1ERFL,
+    &RSCAN0C2ERFL,
+    &RSCAN0C3ERFL,
+    &RSCAN0C4ERFL,
+};
+
+static __IO uint32_t *CFCC_TBL[CAN_NUM][CAN_SND_RCV] = {
+    { &RSCAN0CFCC0 , &RSCAN0CFCC1  },
+    { &RSCAN0CFCC3 , &RSCAN0CFCC4  },
+    { &RSCAN0CFCC6 , &RSCAN0CFCC7  },
+    { &RSCAN0CFCC9 , &RSCAN0CFCC10 },
+    { &RSCAN0CFCC12, &RSCAN0CFCC13 }
+};
+
+static __IO uint32_t *CFSTS_TBL[CAN_NUM][CAN_SND_RCV] = {
+    { &RSCAN0CFSTS0 , &RSCAN0CFSTS1  },
+    { &RSCAN0CFSTS3 , &RSCAN0CFSTS4  },
+    { &RSCAN0CFSTS6 , &RSCAN0CFSTS7  },
+    { &RSCAN0CFSTS9 , &RSCAN0CFSTS10 },
+    { &RSCAN0CFSTS12, &RSCAN0CFSTS13 }
+};
+
+static __IO uint32_t *CFPCTR_TBL[CAN_NUM][CAN_SND_RCV] = {
+    { &RSCAN0CFPCTR0 , &RSCAN0CFPCTR1  },
+    { &RSCAN0CFPCTR3 , &RSCAN0CFPCTR4  },
+    { &RSCAN0CFPCTR6 , &RSCAN0CFPCTR7  },
+    { &RSCAN0CFPCTR9 , &RSCAN0CFPCTR10 },
+    { &RSCAN0CFPCTR12, &RSCAN0CFPCTR13 }
+};
+
+static __IO uint32_t *CFID_TBL[CAN_NUM][CAN_SND_RCV] = {
+    { &RSCAN0CFID0 , &RSCAN0CFID1  },
+    { &RSCAN0CFID3 , &RSCAN0CFID4  },
+    { &RSCAN0CFID6 , &RSCAN0CFID7  },
+    { &RSCAN0CFID9 , &RSCAN0CFID10 },
+    { &RSCAN0CFID12, &RSCAN0CFID13 }
+};
+
+static __IO uint32_t *CFPTR_TBL[CAN_NUM][CAN_SND_RCV] = {
+    { &RSCAN0CFPTR0 , &RSCAN0CFPTR1  },
+    { &RSCAN0CFPTR3 , &RSCAN0CFPTR4  },
+    { &RSCAN0CFPTR6 , &RSCAN0CFPTR7  },
+    { &RSCAN0CFPTR9 , &RSCAN0CFPTR10 },
+    { &RSCAN0CFPTR12, &RSCAN0CFPTR13 }
+};
+
+static __IO uint32_t *CFDF0_TBL[CAN_NUM][CAN_SND_RCV] = {
+    { &RSCAN0CFDF00 , &RSCAN0CFDF01  },
+    { &RSCAN0CFDF03 , &RSCAN0CFDF04  },
+    { &RSCAN0CFDF06 , &RSCAN0CFDF07  },
+    { &RSCAN0CFDF09 , &RSCAN0CFDF010 },
+    { &RSCAN0CFDF012, &RSCAN0CFDF013 }
+};
+
+static __IO uint32_t *CFDF1_TBL[CAN_NUM][CAN_SND_RCV] = {
+    { &RSCAN0CFDF10 , &RSCAN0CFDF11  },
+    { &RSCAN0CFDF13 , &RSCAN0CFDF14  },
+    { &RSCAN0CFDF16 , &RSCAN0CFDF17  },
+    { &RSCAN0CFDF19 , &RSCAN0CFDF110 },
+    { &RSCAN0CFDF112, &RSCAN0CFDF113 }
+};
+
+static const can_info_int_t can_int_info[CAN_NUM][IRQ_NUM] = 
+{
+    {   /* ch0 */
+        { INTRCAN0REC_IRQn, can0_rec_irq         }, /* RxIrq */
+        { INTRCAN0TRX_IRQn, can0_trx_irq         }, /* TxIrq */
+        { INTRCAN0ERR_IRQn, can0_err_warning_irq }, /* EwIrq */
+        { INTRCAN0ERR_IRQn, can0_overrun_irq     }, /* DoIrq */
+        { INTRCAN0ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
+        { INTRCAN0ERR_IRQn, can0_passive_irq     }, /* EpIrq */
+        { INTRCAN0ERR_IRQn, can0_arb_lost_irq    }, /* AlIrq */
+        { INTRCAN0ERR_IRQn, can0_bus_err_irq     }  /* BeIrq */
+    },
+    {   /* ch1 */
+        { INTRCAN1REC_IRQn, can1_rec_irq         }, /* RxIrq */
+        { INTRCAN1TRX_IRQn, can1_trx_irq         }, /* TxIrq */
+        { INTRCAN1ERR_IRQn, can1_err_warning_irq }, /* EwIrq */
+        { INTRCAN1ERR_IRQn, can1_overrun_irq     }, /* DoIrq */
+        { INTRCAN1ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
+        { INTRCAN1ERR_IRQn, can1_passive_irq     }, /* EpIrq */
+        { INTRCAN1ERR_IRQn, can1_arb_lost_irq    }, /* AlIrq */
+        { INTRCAN1ERR_IRQn, can1_bus_err_irq     }  /* BeIrq */
+    },
+    {   /* ch2 */
+        { INTRCAN2REC_IRQn, can2_rec_irq         }, /* RxIrq */
+        { INTRCAN2TRX_IRQn, can2_trx_irq         }, /* TxIrq */
+        { INTRCAN2ERR_IRQn, can2_err_warning_irq }, /* EwIrq */
+        { INTRCAN2ERR_IRQn, can2_overrun_irq     }, /* DoIrq */
+        { INTRCAN2ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
+        { INTRCAN2ERR_IRQn, can2_passive_irq     }, /* EpIrq */
+        { INTRCAN2ERR_IRQn, can2_arb_lost_irq    }, /* AlIrq */
+        { INTRCAN2ERR_IRQn, can2_bus_err_irq     }  /* BeIrq */
+    },
+    {   /* ch3 */
+        { INTRCAN3REC_IRQn, can3_rec_irq         }, /* RxIrq */
+        { INTRCAN3TRX_IRQn, can3_trx_irq         }, /* TxIrq */
+        { INTRCAN3ERR_IRQn, can3_err_warning_irq }, /* EwIrq */
+        { INTRCAN3ERR_IRQn, can3_overrun_irq     }, /* DoIrq */
+        { INTRCAN3ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
+        { INTRCAN3ERR_IRQn, can3_passive_irq     }, /* EpIrq */
+        { INTRCAN3ERR_IRQn, can3_arb_lost_irq    }, /* AlIrq */
+        { INTRCAN3ERR_IRQn, can3_bus_err_irq     }  /* BeIrq */
+    },
+    {   /* ch4 */
+        { INTRCAN4REC_IRQn, can4_rec_irq         }, /* RxIrq */
+        { INTRCAN4TRX_IRQn, can4_trx_irq         }, /* TxIrq */
+        { INTRCAN4ERR_IRQn, can4_err_warning_irq }, /* EwIrq */
+        { INTRCAN4ERR_IRQn, can4_overrun_irq     }, /* DoIrq */
+        { INTRCAN4ERR_IRQn, NULL                 }, /* WuIrq(not supported) */
+        { INTRCAN4ERR_IRQn, can4_passive_irq     }, /* EpIrq */
+        { INTRCAN4ERR_IRQn, can4_arb_lost_irq    }, /* AlIrq */
+        { INTRCAN4ERR_IRQn, can4_bus_err_irq     }  /* BeIrq */
+    }
+};
+
+static __IO uint32_t *dmy_gaflid = &RSCAN0GAFLID0;
+static __IO uint32_t *dmy_gaflm  = &RSCAN0GAFLM0;
+static __IO uint32_t *dmy_gaflp0 = &RSCAN0GAFLP00;
+static __IO uint32_t *dmy_gaflp1 = &RSCAN0GAFLP10;
+
+void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
+    irq_handler = handler;
+    can_irq_id[obj->ch] = id;
+}
+
+void can_irq_free(can_t *obj) {
+    can_irq_id[obj->ch] = 0;
+}
+
+void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
+    __IO uint32_t *dmy_ctr;
+
+    /* Wake-up Irq is not supported */
+    if (type != IRQ_WAKEUP) {
+        if (enable) {
+            dmy_ctr = CTR_MATCH[obj->ch];
+            if (type == IRQ_ERROR) {
+                /* EWIE interrupts is enable */
+                *dmy_ctr |= 0x00000200;
+            } else if (type == IRQ_OVERRUN) {
+                /* OLIE interrupts is enable */
+                *dmy_ctr |= 0x00002000;
+            } else if (type == IRQ_PASSIVE) {
+                /* EPIE interrupts is enable */
+                *dmy_ctr |= 0x00000400;
+            } else if (type == IRQ_ARB) {
+                /* ALIE interrupts is enable */
+                *dmy_ctr |= 0x00008000;
+            } else if (type == IRQ_BUS) {
+                /* BEIE interrupts is enable */
+                *dmy_ctr |= 0x00000100;
+            }
+            InterruptHandlerRegister(can_int_info[obj->ch][type].int_num, can_int_info[obj->ch][type].handler);
+            GIC_SetPriority(can_int_info[obj->ch][type].int_num, 5);
+            GIC_EnableIRQ(can_int_info[obj->ch][type].int_num);
+        } else {
+            GIC_DisableIRQ(can_int_info[obj->ch][type].int_num);
+        }
+    }
+}
+
+static void can_rec_irq(uint32_t ch) {
+    __IO uint32_t *dmy_cfsts;
+
+    dmy_cfsts = CFSTS_TBL[ch][CAN_RECV];
+    *dmy_cfsts &= 0xFFFFFFF7;           // Clear CFRXIF
+
+    irq_handler(can_irq_id[ch], IRQ_RX);
+}
+
+static void can_trx_irq(uint32_t ch) {
+    __IO uint32_t *dmy_cfsts;
+
+    dmy_cfsts = CFSTS_TBL[ch][CAN_SEND];
+    *dmy_cfsts &= 0xFFFFFFEF;           // Clear CFTXIF
+
+    irq_handler(can_irq_id[ch], IRQ_TX);
+}
+
+static void can_err_irq(uint32_t ch, CanIrqType type) {
+    __IO uint32_t *dmy_erfl;
+    int val = 1;
+    
+    dmy_erfl = ERFL_MATCH[ch];
+    switch (type) {
+        case IRQ_ERROR:
+            *dmy_erfl &= 0xFFFFFFFD;    // Clear EWF
+            break;
+        case IRQ_OVERRUN:
+            *dmy_erfl &= 0xFFFFFFDF;    // Clear OVLF
+            break;
+        case IRQ_PASSIVE:
+            *dmy_erfl &= 0xFFFFFFFB;    // Clear EPF
+            break;
+        case IRQ_ARB:
+            *dmy_erfl &= 0xFFFFFF7F;    // Clear ALF
+            break;
+        case IRQ_BUS:
+            *dmy_erfl &= 0xFFFF00FF;    // Clear ADERRAB0ERRAB1ERRACERRAAERRAFERRASERR
+            *dmy_erfl &= 0xFFFFFFFE;    // Clear BEF
+            break;
+        case IRQ_WAKEUP:
+            /* not supported */
+            /* fall through */
+        default:
+            val = 0;
+            break;
+    }
+    if (val == 1) {
+        irq_handler(can_irq_id[ch], type);
+    }
+}
+
+static void can0_rec_irq(void) {
+    can_rec_irq(CAN_0);
+}
+
+static void can1_rec_irq(void) {
+    can_rec_irq(CAN_1);
+}
+
+static void can2_rec_irq(void) {
+    can_rec_irq(CAN_2);
+}
+
+static void can3_rec_irq(void) {
+    can_rec_irq(CAN_3);
+}
+
+static void can4_rec_irq(void) {
+    can_rec_irq(CAN_4);
+}
+
+static void can0_trx_irq(void) {
+    can_trx_irq(CAN_0);
+}
+
+static void can1_trx_irq(void) {
+    can_trx_irq(CAN_1);
+}
+
+static void can2_trx_irq(void) {
+    can_trx_irq(CAN_2);
+}
+
+static void can3_trx_irq(void) {
+    can_trx_irq(CAN_3);
+}
+
+static void can4_trx_irq(void) {
+    can_trx_irq(CAN_4);
+}
+
+static void can0_err_warning_irq(void) {
+    can_err_irq(CAN_0, IRQ_ERROR);
+}
+
+static void can1_err_warning_irq(void) {
+    can_err_irq(CAN_1, IRQ_ERROR);
+}
+
+static void can2_err_warning_irq(void) {
+    can_err_irq(CAN_2, IRQ_ERROR);
+}
+
+static void can3_err_warning_irq(void) {
+    can_err_irq(CAN_3, IRQ_ERROR);
+}
+
+static void can4_err_warning_irq(void) {
+    can_err_irq(CAN_4, IRQ_ERROR);
+}
+
+static void can0_overrun_irq(void) {
+    can_err_irq(CAN_0, IRQ_OVERRUN);
+}
+
+static void can1_overrun_irq(void) {
+    can_err_irq(CAN_1, IRQ_OVERRUN);
+}
+
+static void can2_overrun_irq(void) {
+    can_err_irq(CAN_2, IRQ_OVERRUN);
+}
+
+static void can3_overrun_irq(void) {
+    can_err_irq(CAN_3, IRQ_OVERRUN);
+}
+
+static void can4_overrun_irq(void) {
+    can_err_irq(CAN_4, IRQ_OVERRUN);
+}
+
+static void can0_passive_irq(void) {
+    can_err_irq(CAN_0, IRQ_PASSIVE);
+}
+
+static void can1_passive_irq(void) {
+    can_err_irq(CAN_1, IRQ_PASSIVE);
+}
+
+static void can2_passive_irq(void) {
+    can_err_irq(CAN_2, IRQ_PASSIVE);
+}
+
+static void can3_passive_irq(void) {
+    can_err_irq(CAN_3, IRQ_PASSIVE);
+}
+
+static void can4_passive_irq(void) {
+    can_err_irq(CAN_4, IRQ_PASSIVE);
+}
+
+static void can0_arb_lost_irq(void) {
+    can_err_irq(CAN_0, IRQ_ARB);
+}
+
+static void can1_arb_lost_irq(void) {
+    can_err_irq(CAN_1, IRQ_ARB);
+}
+
+static void can2_arb_lost_irq(void) {
+    can_err_irq(CAN_2, IRQ_ARB);
+}
+
+static void can3_arb_lost_irq(void) {
+    can_err_irq(CAN_3, IRQ_ARB);
+}
+
+static void can4_arb_lost_irq(void) {
+    can_err_irq(CAN_4, IRQ_ARB);
+}
+
+static void can0_bus_err_irq(void) {
+    can_err_irq(CAN_0, IRQ_BUS);
+}
+
+static void can1_bus_err_irq(void) {
+    can_err_irq(CAN_1, IRQ_BUS);
+}
+
+static void can2_bus_err_irq(void) {
+    can_err_irq(CAN_2, IRQ_BUS);
+}
+
+static void can3_bus_err_irq(void) {
+    can_err_irq(CAN_3, IRQ_BUS);
+}
+
+static void can4_bus_err_irq(void) {
+    can_err_irq(CAN_4, IRQ_BUS);
+}
+
+void can_init(can_t *obj, PinName rd, PinName td) {
+    __IO uint32_t *dmy_ctr;
+
+    /* determine the CAN to use */
+    uint32_t can_rx = pinmap_peripheral(rd, PinMap_CAN_RD);
+    uint32_t can_tx = pinmap_peripheral(td, PinMap_CAN_TD);
+    obj->ch = pinmap_merge(can_tx, can_rx);
+    MBED_ASSERT((int)obj->ch != NC);
+
+    /* enable CAN clock */
+    CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP32);
+    /* Has CAN RAM initialisation completed ? */
+    while ((RSCAN0GSTS & 0x08) == 0x08) {
+        __NOP();
+    }
+    /* clear Global Stop mode bit */
+    RSCAN0GCTR &= 0xFFFFFFFB;
+    /* clear Channel Stop mode bit */
+    dmy_ctr = CTR_MATCH[obj->ch];
+    *dmy_ctr &= 0xFFFFFFFB;
+    /* Enter global reset mode */
+    can_set_global_mode(GL_RESET);
+    /* Enter channel reset mode */
+    can_set_channel_mode(obj->ch, CH_RESET);
+    /* reset register */
+    can_reset_reg(obj);
+
+    can_initialized[obj->ch] = 1;
+    /* reconfigure channel which is already initialized */
+    can_reconfigure_channel();
+    
+    /* pin out the can pins */
+    pinmap_pinout(rd, PinMap_CAN_RD);
+    pinmap_pinout(td, PinMap_CAN_TD);
+}
+
+void can_free(can_t *obj) {
+    /* disable CAN clock */
+    CPGSTBCR3 |= CPG_STBCR3_BIT_MSTP32;
+}
+
+int can_frequency(can_t *obj, int f) {
+    int retval = 0;
+    
+    if (f <= 1000000) {
+        /* less than 1Mhz */
+        /* set Channel Reset mode */
+        can_set_channel_mode(obj->ch, CH_RESET);
+        can_set_frequency(obj, f);
+        /* set Channel Communication mode */
+        can_set_channel_mode(obj->ch, CH_COMM);
+        retval = 1;
+    }
+
+    return retval;
+}
+
+void can_reset(can_t *obj) {
+    /* Enter global reset mode */
+    can_set_global_mode(GL_RESET);
+    /* Enter channel reset mode */
+    can_set_channel_mode(obj->ch, CH_RESET);
+    /* reset register */
+    can_reset_reg(obj);
+    /* reconfigure channel which is already initialized */
+    can_reconfigure_channel();
+}
+
+int can_write(can_t *obj, CAN_Message msg, int cc) {
+    __IO uint32_t *dmy_sts;
+    __IO uint32_t *dmy_cfsts;
+    __IO uint32_t *dmy_cfid;
+    __IO uint32_t *dmy_cfptr;
+    __IO uint32_t *dmy_cfdf0;
+    __IO uint32_t *dmy_cfdf1;
+    __IO uint32_t *dmy_cfpctr;
+    int retval = 0;
+
+    /* Wait to become channel communication mode */
+    dmy_sts = STS_MATCH[obj->ch];
+    while ((*dmy_sts & 0x07) != 0) {
+        __NOP();
+    }
+    
+    if (((msg.format == CANStandard) && (msg.id <= 0x07FF)) || ((msg.format == CANExtended) && (msg.id <= 0x03FFFF))) {
+        /* send/receive FIFO buffer isn't full */
+        dmy_cfsts = CFSTS_TBL[obj->ch][CAN_SEND];
+        if ((*dmy_cfsts & 0x02) != 0x02) {
+            /* set format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
+            dmy_cfid = CFID_TBL[obj->ch][CAN_SEND];
+            *dmy_cfid = ((msg.format << 31) | (msg.type << 30));
+            if (msg.format == CANStandard) {
+                *dmy_cfid |= (msg.id & 0x07FF);
+            } else {
+                *dmy_cfid |= ((msg.id & 0x03FFFF) << 11);
+            }
+            /* set length */
+            dmy_cfptr = CFPTR_TBL[obj->ch][CAN_SEND];
+            *dmy_cfptr = msg.len << 28;
+            /* set data */
+            dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_SEND];
+            memcpy((void *)dmy_cfdf0, &msg.data[0], 4);
+            dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_SEND];
+            memcpy((void *)dmy_cfdf1, &msg.data[4], 4);
+            /* send request */
+            dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_SEND];
+            *dmy_cfpctr = 0xFF;
+            retval = 1;
+        }
+    }
+    
+    return retval;
+}
+
+int can_read(can_t *obj, CAN_Message *msg, int handle) {
+    __IO uint32_t *dmy_sts;
+    __IO uint32_t *dmy_cfsts;
+    __IO uint32_t *dmy_cfid;
+    __IO uint32_t *dmy_cfptr;
+    __IO uint32_t *dmy_cfdf0;
+    __IO uint32_t *dmy_cfdf1;
+    __IO uint32_t *dmy_cfpctr;
+    int retval = 0;
+
+    /* Wait to become channel communication mode */
+    dmy_sts = STS_MATCH[obj->ch];
+    while ((*dmy_sts & 0x07) != 0) {
+        __NOP();
+    }
+    
+    /* send/receive FIFO buffer isn't empty */
+    dmy_cfsts = CFSTS_TBL[obj->ch][CAN_RECV];
+    while ((*dmy_cfsts & 0x01) != 0x01) {
+        /* get format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
+        dmy_cfid = CFID_TBL[obj->ch][CAN_RECV];
+        msg->format = (CANFormat)(*dmy_cfid >> 31);
+        msg->type = (CANType)(*dmy_cfid >> 30);
+        if (msg->format == CANStandard) {
+            msg->id = (*dmy_cfid & 0x07FF);
+        } else {
+            msg->id = ((*dmy_cfid >> 11) & 0x03FFFF);
+        }
+        /* get length */
+        dmy_cfptr = CFPTR_TBL[obj->ch][CAN_RECV];
+        msg->len = (unsigned char)(*dmy_cfptr >> 28);
+        /* get data */
+        dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_RECV];
+        memcpy(&msg->data[0], (void *)dmy_cfdf0, 4);
+        dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_RECV];
+        memcpy(&msg->data[4], (void *)dmy_cfdf1, 4);
+        /* receive(next data) request */
+        dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_RECV];
+        *dmy_cfpctr = 0xFF;
+        retval = 1;
+    }
+    
+    return retval;
+}
+
+unsigned char can_rderror(can_t *obj) {
+    __IO uint32_t *dmy_sts;
+    
+    dmy_sts = STS_MATCH[obj->ch];
+    return (unsigned char)((*dmy_sts >> 16) & 0xFF);
+}
+
+unsigned char can_tderror(can_t *obj) {
+    __IO uint32_t *dmy_sts;
+    
+    dmy_sts = STS_MATCH[obj->ch];
+    return (unsigned char)((*dmy_sts >> 24) & 0xFF);
+}
+
+int can_mode(can_t *obj, CanMode mode) {
+    __IO uint32_t *dmy_ctr;
+    __IO uint32_t *dmy_sts;
+    __IO uint32_t *dmy_cfcc;
+    int ch_cnt;
+    can_t *tmp_obj;
+    tmp_obj = obj;
+    int retval = 1;
+    
+    switch (mode) {
+        case MODE_RESET:
+            can_set_global_mode(GL_RESET);
+            can_set_channel_mode(obj->ch, CH_RESET);
+            for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
+                can_initialized[ch_cnt] = 0;
+            }
+            break;
+        case MODE_NORMAL:
+            can_set_global_mode(GL_OPE);
+            can_set_channel_mode(obj->ch, CH_COMM);
+            break;
+        case MODE_SILENT:
+            can_set_channel_mode(obj->ch, CH_HOLD);
+            /* set listen only mode, enable communication test mode */
+            dmy_ctr = CTR_MATCH[obj->ch];
+            *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
+            can_set_channel_mode(obj->ch, CH_COMM);
+            break;
+        case MODE_TEST_LOCAL:
+            can_set_channel_mode(obj->ch, CH_HOLD);
+            /* set self test mode 0, enable communication test mode */
+            dmy_ctr = CTR_MATCH[obj->ch];
+            *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x05000000);
+            can_set_channel_mode(obj->ch, CH_COMM);
+            break;
+        case MODE_TEST_GLOBAL:
+            /* set the channel between the communication test on channel 1 and channel 2 */
+            /* set Channel Hold mode */
+            for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
+                dmy_sts = STS_MATCH[tmp_obj->ch];
+                if ((*dmy_sts & 0x04) == 0x04) {
+                    /* Channel Stop mode */
+                    /* clear Channel Stop mode bit */
+                    dmy_ctr = CTR_MATCH[tmp_obj->ch];
+                    *dmy_ctr &= 0xFFFFFFFB;
+                    can_set_channel_mode(tmp_obj->ch, CH_RESET);
+                }
+                can_set_channel_mode(tmp_obj->ch, CH_HOLD);
+            }
+            can_set_global_mode(GL_TEST);
+            /* enable communication test between channel1 and channel2 */
+            RSCAN0GTSTCFG = 0x06;
+            RSCAN0GTSTCTR = 0x01;
+            /* send and receive setting of channel1 and channel2 */
+            for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
+                can_reset_buffer(tmp_obj);
+                /* set global interrrupt */
+                /* THLEIE, MEIE and DEIE interrupts are disable */
+                RSCAN0GCTR &= 0xFFFFF8FF;
+                /* BLIE, OLIE, BORIE and BOEIE interrupts are disable */
+                /* TAIE, ALIE, EPIE, EWIE and BEIE interrupts are enable */
+                dmy_ctr = CTR_MATCH[tmp_obj->ch];
+                *dmy_ctr &= 0x00018700;
+                can_set_global_mode(GL_OPE);
+                can_set_channel_mode(tmp_obj->ch, CH_COMM);
+                /* Use send/receive FIFO buffer */
+                dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_SEND];
+                *dmy_cfcc |= 0x01;
+                dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_RECV];
+                *dmy_cfcc |= 0x01;
+            }
+            break;
+        case MODE_TEST_SILENT:
+            /* not supported */
+            /* fall through */
+        default:
+            retval = 0;
+            break;
+    }
+    
+    return retval;
+}
+
+int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
+    int retval = 0;
+    
+    if ((format == CANStandard) || (format == CANExtended)) {
+        if (((format == CANStandard) && (id <= 0x07FF)) || ((format == CANExtended) && (id <= 0x03FFFF))) {
+            /* set Global Reset mode and Channel Reset mode */
+            can_set_global_mode(GL_RESET);
+            can_set_channel_mode(obj->ch, CH_RESET);
+            /* enable receive rule table writing */
+            RSCAN0GAFLECTR = 0x00000100;
+            /* set the page number of receive rule table(page number = 0) */
+            RSCAN0GAFLECTR |= (obj->ch * 4);
+            /* set IDE format */
+            *dmy_gaflid = (format << 31);
+            if (format == CANExtended) {
+                /* set receive rule ID for bit28-11 */
+                *dmy_gaflid |= (id << 11);
+            } else {
+                /* set receive rule ID for bit10-0 */
+                *dmy_gaflid |= id;
+            }
+            /* set ID mask bit */
+            *dmy_gaflm = (0xC0000000 | mask);
+            /* disable receive rule table writing */
+            RSCAN0GAFLECTR &= 0xFFFFFEFF;
+            /* reconfigure channel which is already initialized */
+            can_reconfigure_channel();
+            retval = 1;
+        }
+    }
+    
+    return retval;
+}
+
+void can_monitor(can_t *obj, int silent) {
+    __IO uint32_t *dmy_ctr;
+
+    /* set Channel Hold mode */
+    can_set_channel_mode(obj->ch, CH_HOLD);
+    if (silent) {
+        /* set listen only mode, enable communication test mode */
+        dmy_ctr = CTR_MATCH[obj->ch];
+        *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
+        can_set_channel_mode(obj->ch, CH_COMM);
+    } else {
+        /* set normal test mode, disable communication test mode */
+        dmy_ctr = CTR_MATCH[obj->ch];
+        *dmy_ctr &= 0x00FFFFFF;
+        /* reset register */
+        can_reset_reg(obj);
+        /* reconfigure channel which is already initialized */
+        can_reconfigure_channel();
+    }
+}
+
+static void can_reset_reg(can_t *obj) {
+    __IO uint32_t *dmy_ctr;
+
+    /* time stamp source uses peripheral clock (pclk(P1_phi)/2), CAN clock uses clkc(P1_phi/2),           */
+    /* mirror off, DLC not transfer, DLC check permit, transmit buffer priority, clock source not divided */
+    RSCAN0GCFG = 0x00000003;
+    /* set default frequency at 100k */
+    can_set_frequency(obj, 100000);
+    /* set receive rule */
+    can_reset_recv_rule(obj);
+    /* set buffer */
+    can_reset_buffer(obj);
+    /* set global interrrupt */
+    /* THLEIE, MEIE and DEIE interrupts are disable */
+    RSCAN0GCTR &= 0xFFFFF8FF;
+    /* ALIE, BLIE, OLIE, BORIE, BOEIE, EPIE, EWIE and BEIE interrupts are disable */
+    dmy_ctr = CTR_MATCH[obj->ch];
+    *dmy_ctr &= 0xFFFF00FF;
+}
+
+static void can_reset_recv_rule(can_t *obj) {
+    /* number of receive rules of each chanel = 64 */
+    RSCAN0GAFLCFG0 = 0x40404040;
+    RSCAN0GAFLCFG1 = 0x40000000;
+    /* enable receive rule table writing */
+    RSCAN0GAFLECTR = 0x00000100;
+    /* set the page number of receive rule table(ex: id ch = 1, page number = 4) */
+    RSCAN0GAFLECTR |= (obj->ch * 4);
+    /* set standard ID, data frame and receive rule ID */
+    *dmy_gaflid = 0x07FF;
+    /* IDE bit, RTR bit and ID bit(28-0) are not compared */
+    *dmy_gaflm = 0;
+    /* DLC check is 1 bytes, not use a receive buffer */
+    *dmy_gaflp0 = 0x10000000;
+    /* use a send/receive FIFO buffer(ex: if ch = 1, FIFO buffer number = 4 and bit = 12) */
+    *dmy_gaflp1 = (1 << ((obj->ch + 3) * 3));
+    /* disable receive rule table writing */
+    RSCAN0GAFLECTR &= 0xFFFFFEFF;
+}
+
+static void can_reset_buffer(can_t *obj) {
+    __IO uint32_t *dmy_rfcc;
+    __IO uint32_t *dmy_cfcc;
+    __IO uint32_t *dmy_txqcc;
+    __IO uint32_t *dmy_thlcc;
+    int cnt;
+    
+    /* set linked send buffer number(ex: if ch = 1 and mode = send, buffer number = 16), interval timer is pclk/2 */
+    /* number of rows of send/receive FIFO buffer = 4 */
+    dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
+    *dmy_cfcc = 0x00011100;                 /* send/receive FIFO mode is send */
+    dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
+    *dmy_cfcc = 0x00001100;                 /* send/receive FIFO mode is receive */
+    /* receive buffer is not used */
+    RSCAN0RMNB = 0;
+    /* receive FIFO buffer is not used */
+    for (cnt = 0; cnt < 8; cnt++) {
+        dmy_rfcc = RFCC_MATCH[cnt];
+        *dmy_rfcc = 0;
+    }
+    /* send queue is not used */
+    dmy_txqcc = TXQCC_MATCH[obj->ch];
+    *dmy_txqcc = 0;
+    /* send history is not used */
+    dmy_thlcc = THLCC_MATCH[obj->ch];
+    *dmy_thlcc = 0;
+
+    /* CFTXIE and CFRXIE interrupts are enable */
+    dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
+    *dmy_cfcc |= 0x04;
+    dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
+    *dmy_cfcc |= 0x02;
+    /* TMIEp interrupt is disable */
+    RSCAN0TMIEC0 = 0x00000000;
+    RSCAN0TMIEC1 = 0x00000000;
+    RSCAN0TMIEC2 = 0x00000000;
+}
+
+static void can_reconfigure_channel(void) {
+    __IO uint32_t *dmy_cfcc;
+    int ch_cnt;
+
+    for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
+        if (can_initialized[ch_cnt] == 1) {
+            /* set Global Operation mode and Channel Communication mode */
+            can_set_global_mode(GL_OPE);
+            can_set_channel_mode(ch_cnt, CH_COMM);
+            /* Use send/receive FIFO buffer */
+            dmy_cfcc = CFCC_TBL[ch_cnt][CAN_SEND];
+            *dmy_cfcc |= 0x01;
+            dmy_cfcc = CFCC_TBL[ch_cnt][CAN_RECV];
+            *dmy_cfcc |= 0x01;
+        }
+    }
+}
+
+static void can_set_frequency(can_t *obj, int f) {
+    __IO uint32_t *dmy_cfg;
+    int oldfreq = 0;
+    int newfreq = 0;
+    uint32_t  clkc_val;
+    uint8_t tmp_tq;
+    uint8_t tq = 0;
+    uint8_t tmp_brp;
+    uint8_t brp = 0;
+    uint8_t tseg1 = 0;
+    uint8_t tseg2 = 0;
+    
+    /* set clkc */
+    if (RZ_A1_IsClockMode0() == false) {
+        clkc_val = CM1_RENESAS_RZ_A1_P1_CLK / 2;
+    } else {
+        clkc_val = CM0_RENESAS_RZ_A1_P1_CLK / 2;
+    }
+    /* calculate BRP bit and Choose max value of calculated frequency */
+    for (tmp_tq = 8; tmp_tq <= 25; tmp_tq++) {
+        /* f = fCAN / ((BRP+1) * Tq) */
+        /* BRP = (fCAN / (f * Tq)) - 1 */
+        tmp_brp = ((clkc_val / (f * tmp_tq)) - 1) + 1;   // carry(decimal point is carry)
+        newfreq = clkc_val / ((tmp_brp + 1) * tmp_tq);
+        if (newfreq >= oldfreq) {
+            oldfreq  = newfreq;
+            tq       = tmp_tq;
+            brp      = tmp_brp;
+        }
+    }
+    /* calculate TSEG1 bit and TSEG2 bit */
+    tseg1 = (tq - 1) * 0.666666667;
+    tseg2 = (tq - 1) - tseg1;
+    /* set RSCAN0CmCFG register */
+    dmy_cfg = CFG_MATCH[obj->ch];
+    *dmy_cfg = ((tseg2 - 1) << 20) | ((tseg1 - 1) << 16) | brp;
+}
+
+static void can_set_global_mode(int mode) {
+    /* set Global mode */
+    RSCAN0GCTR = ((RSCAN0GCTR & 0xFFFFFFFC) | mode);
+    /* Wait to cahnge into Global XXXX mode */
+    while ((RSCAN0GSTS & 0x07) != mode) {
+        __NOP();
+    }
+}
+
+static void can_set_channel_mode(uint32_t ch, int mode) {
+    __IO uint32_t *dmy_ctr;
+    __IO uint32_t *dmy_sts;
+
+    /* set Channel mode */
+    dmy_ctr = CTR_MATCH[ch];
+    *dmy_ctr = ((*dmy_ctr & 0xFFFFFFFC) | mode);
+    /* Wait to cahnge into Channel XXXX mode */
+    dmy_sts = STS_MATCH[ch];
+    while ((*dmy_sts & 0x07) != mode) {
+        __NOP();
+    }
+}
+