# CAN 筆記 [TOC] ## 進入 error passive state * 若 channel 進入 error passive state (m=channl no.) * RSCAN0CmSTS 的 EPSTS[3] flag 會被設起來 * RSCAN0CmERFL 的 EPF[3] flag 會被設起來 * RSCAN0CmSTS -> EPSTS Flag * This flag is set to 1 when the RS-CAN module has entered the error passive state ((128 ≤ TEC[7:0] ≤ 255) or (128 ≤ REC[7:0])), It is cleared to 0 when the RS-CAN module has exited the error passive state or has entered channel reset mode. ![](https://i.imgur.com/mOMDlpq.png) * RSCAN0CmERFL -> EPF Flag * This flag becomes 1 when the error passive state is reached (REC[7:0] or TEC[7:0] value > 127). This flag becomes 1 only when the REC[7:0] or TEC[7:0] value first exceeds 127. Therefore, if the program writes 0 to this flag while the value of REC[7:0] or TEC[7:0] remains over 127, this bit is not set to 1 until both REC [7:0] and TEC[7:0] values become 127 or less and then the REC[7:0] or TEC[7:0] value exceeds 127 again. ![](https://i.imgur.com/XFdMyug.png) ## RH850f1l RSCAN Channel Mode * Channel Stop Mode * In channel stop mode, clocks are not supplied to channels and therefore <font color="#f00">power consumption is reduced</font>. * CAN registers can be read, but writing data to them is prohibited. Register values are retained. * Each channel enters channel stop mode after the MCU is reset. Channels also transition to channel stop mode when the CSLPR bit in the RSCAN0CmCTR register (m = 0 to 5) is set to 1 (channel stop mode) in channel reset mode. The CSLPR bit should not be modified in channel communication mode and channel halt mode. * Channel Reset Mode * **Performs initial settings for the channels.** * In channel reset mode, channel settings are performed. When a channel transitions to channel reset mode, some channel-related registers are initialized. Table 19.93 lists the registers to be initialized. * When the CHMDC[1:0] bits in the RSCAN0CmCTR register are set to 01B (channel reset mode) during CAN communication, communication is terminated before it is completed and the channel transitions to channel reset mode. Table 19.92 shows the operation when the CHMDC[1:0] bits are set to 01B (channel reset mode) during CAN communication. * Channel Halt Mode * Stops CAN communication and allows channel testing. * flow of OSEK_NM does not correspond to this mode * Channel Communication Mode * **Performs CAN communication.** * In channel communication mode, CAN communication is performed. Each channel has the following communication states during CAN communication. * Idle: * Neither reception nor transmission is in progress. * Reception: * Receiving a message sent from another node. * Transmission: * Transmitting a message. * Bus-off: * Isolated from CAN communication. * When the CHMDC[1:0] bits in the RSCAN0CmCTR register are set to 00B, the channel transitions to channel communication mode. After that, once 11 consecutive recessive bits have been detected, the COMSTS flag in the RSCAN0CmSTS register (m = 0 to 5) is set to 1 (communication is ready) and transmission and reception are enabled on the CAN network as an active node. At this time, transmission and reception of messages can be started. * Channel Mode State Transition Chart ![](https://i.imgur.com/NUIB9jW.png) * RSCAN0CmCTR ![](https://i.imgur.com/PKQCg5r.png) ![](https://i.imgur.com/6eWqazy.png) ![](https://i.imgur.com/aUMVUDq.png) ![](https://i.imgur.com/MJXcudz.png) ![](https://i.imgur.com/RvJKcxC.png) ![](https://i.imgur.com/hWIkwqz.png) ![](https://i.imgur.com/xPBT0Ve.png) ![](https://i.imgur.com/uCgZHWo.png) * RSCAN0CmSTS ![](https://i.imgur.com/oElzcH2.png) ![](https://i.imgur.com/0O6a3e5.png) ![](https://i.imgur.com/xwI4Rqg.png) ![](https://i.imgur.com/ja2MdIs.png) ![](https://i.imgur.com/568jZY5.png) ## RH850f1l RSCAN wake-up setting * Transition to Stand-By Mode ![](https://i.imgur.com/ecZnina.png) * Wake-Up Factor 1 Register Assignment ![](https://i.imgur.com/oHGgETc.png) * Set-up Procedure ![](https://i.imgur.com/4Xw7WV6.png) ## RH850f1l CAN Bus-Off State * RSCAN0CmCTR Register Contents ![](https://i.imgur.com/UznEZrc.png) ![](https://i.imgur.com/S0UlXpY.png) * BOM[1:0] Bits * A channel transitions to the bus-off state according to the transmit/receive error counter increment/ decrement rules of the CAN specifications. * The conditions for returning from the bus-off state are determined by the BOM[1:0] bits in the RSCAN0CmCTR register. * When BOM[1:0] = 00B: * Bus-off recovery is compliant with the CAN specifications. After 11 consecutive recessive bits have been detected 128 times, a channel returns from the bus-off state to the CAN communication ready state (error active state). At that time, the TEC[7:0] and REC[7:0] bits in the RSCAN0CmSTS register are initialized to 00H, the BORF flag in the RSCAN0CmERFL register is set to 1 (bus-off recovery is detected), and a bus-off recovery interrupt request is generated. When the CHMDC[1:0] bits in the RSCAN0CmCTR register are set to 10B (channel halt mode) in the bus-off state, the channel transitions to channel halt mode after bus-off recovery has been completed (11 consecutive recessive bits have been detected 128 times). * When BOM[1:0] = 01B: * When a channel transitions to the bus-off state, the CHMDC[1:0] bits are set to 10B and the channel transitions to channel halt mode. At that time, the TEC[7:0] and REC[7:0] bits are initialized to 00H. The BORF flag is not set to 1, and bus-off recovery interrupt request is not generated. * When BOM[1:0] = 10B: * When a channel has transitioned to the bus-off state, the CHMDC[1:0] bits are set to 10B. After bus-off recovery has been completed (11 consecutive recessive bits have been detected 128 times), the channel transitions to channel halt mode. At that time, the TEC[7:0] and REC[7:0] bits are initialized to 00H, the BORF flag is set to 1, and a bus-off recovery interrupt request is generated. * When BOM[1:0] = 11B: * When the CHMDC[1:0] bits are set to 10B in the bus-off state, the channel transitions to channel halt mode before bus-off recovery is completed. At that time, the TEC[7:0] and REC[7:0] bits are initialized to 00H, but the BORF flag is not set to 1. Also, a bus-off recovery interrupt is not generated. However, the BORF flag becomes 1 and a bus-off recovery interrupt request is generated if a CAN module transitions to error active state (by detecting 128 times of 11 consecutive recessive bits) before CHMDC[1:0] bits are set to 10B. * If the RS-CAN module causes the channel to transition to channel halt mode simultaneously with a program write to the CHMDC[1:0] bits, the program write takes precedence. An automatic transition to channel halt mode when the BOM[1:0] bits are set to 01B or 10B is made only when the CHMDC[1:0] bits are 00B (channel communication mode). * Furthermore, setting the RTBO bit in the RSCAN0CmCTR register to 1 allows a forced recovery from the bus-off state. As soon as the RTBO bit is set to 1, the state changes to the error active state. After 11 consecutive recessive bits have been detected, the CAN module becomes ready for communication. In this case, the BORF flag is not set to 1 and the TEC[7:0] and REC[7:0] bits are initialized to 00H. Write 1 to the RTBO bit only when the BOM[1:0] value is 00B. Writing the RTBO bit to 1 in a state other than the bus-off state is ignored, and the RTBO bit is immediately set to 0. ## RH850f1l CAN Channel Mode 之間的轉換方式 ### Channel Stop Mode -> Channel Reset Mode * 對應的 DLL Services: * D_Init(BusAwake) * D_Init(BusInit) * RH850f1l_hardware_CAN 轉換方法 ### Channel Reset Mode -> Channel Communication Mode * 對應的 DLL Services: * D_Online * RH850f1l_hardware_CAN 轉換方法 ### Channel Communication Mode -> Channel Reset Mode * 對應的 DLL Services * D_Offline * RH850f1l_hardware_CAN 轉換方法 ### Channel Reset Mode -> Channel Stop Mode * 對應的 DLL Services: * D_Init(BusSleep) * D_Init(BusShutdown) * RH850f1l_hardware_CAN 轉換方法 ## D_Init * OSEK NM 定義: * From the NM point of view, five services to initialize the DLL are needed in general. Parameter are adjusted according to the following examples: - baud rate - sample point - sample algorithm - synchronization mechanism - bit timing - Sleep Mode of the protocol circuit - Sleep Mode of the physical layer - Standby Mode of the physical layer - operation modes of the protocol circuit * Implementation ```clike= void D_Init(NetIdType Id, RoutineRefType initRoutine) { if(initRoutine) initRoutine(Id); } struct { // func pointers to HW init routines, // they depend on the given HW design RoutineRefType busInit; RoutineRefType busAwake; RoutineRefType BusSleep; RoutineRefType busRestart; RoutineRefType busShutDown; } routines; ``` ![](https://i.imgur.com/3Zrl5ws.png) ### BusInitRoutine * OSEK NM 定義: * initialize the bus hardware once at the start of the network * 對照 RH850f1l_hardware_CAN 定義: - [ ] Port Init - [ ] Channel stop mode -> Channel reset mode - [ ] Channel Initilize - [ ] ~~Channel stop mode -> Channel reset mode -> Channel halt mode~~ * 呼叫時機: * startNM -> D_Init(...;BusInit) -> D_online * NMOff -> NMInit -> NMInitReset * 程式操作流程: 1. R_RSCAN0_PORT_Init_Channelm() 2. ### BusAwakeRoutine * OSEK NM 定義: * reinitialize the bus hardware to leave the power down mode * 對照 RH850f1l_hardware_CAN 定義: - [ ] Channel stop mode -> Channel reset mode - [ ] Channel Initilize - [ ] ~~Channel stop mode -> Channel reset mode -> Channel halt mode~~ * 呼叫時機: * Leave NMBusSleep -> D_Init(...;BusAwake) -> D_online * NMBusSleep -> NMInit -> NMInitReset * Leave NMBusSleep 時機: * communication request received * e.g. * GotoMode(Awake) called * wake-up signal from the bus signalled by D_Status.ind * any NM message received ### BusRestartRoutine * OSEK NM 定義: * restart the bus hardware in the case of a fatal bus error * 對照 RH850f1l_hardware_CAN 定義: * if in Channel communication mode (normal case) - [ ] Channel communication mode -> Channel reset mode -> Channel stop mode - [ ] Deinit Port -> Init Port - [ ] Channel stop mode -> Channel reset mode - [ ] Channel Initialize * if in Channel stop mode - [ ] Deinit Port -> Init Port - [ ] Channel stop mode -> Channel reset mode - [ ] Channel Initialize * - [ ] ~~Channel reset mode -> Channel halt mode~~ * 呼叫時機: * D_Status.ind -> D_offline -> D_Init(...;BusRestart) -> D_Online * NMON -> NMInitLimpHome -> NMLimphome ### BusSleepRoutine * OSEK NM 定義: * initialize the power down mode of the bus hardware * 對照 RH850f1l_hardware_CAN 定義: - [ ] Channel communication mode -> Channel reset mode -> Channel stop mode * 呼叫時機: * D_offline -> TO(Twbs) -> D_Init(...;BusSleep) * TwbsNormal -> NMBusSleep * TwbsLimphome -> NMBusSleep ### BusShutdownRoutine * OSEK NM 定義: * shut down the bus hardware * 對照 RH850f1l_hardware_CAN 定義: - [ ] any mode -> Channel stop mode - [ ] Deinit Port * 呼叫時機: * StopNM -> D_Init(...;BusShutDown) * NMOn(any state) -> NMShutDown -> NMOff ## D_Online * OSEK NM 定義: * This service enables the user communication on the data link layer, e.g. after a call of D_Offline. * 對照 RH850f1l_hardware_CAN 定義: * 可能為: - [ ] Channel reset mode -> Channel communication mode(if already in communication mode, skip) - [ ] ~~Channel halt mode -> Channel communication mode~~ - [ ] ~~Channel stop mode -> Channel communication mode~~ * 呼叫時機 * D_Init (...;BusInit) -> D_online * NMInit -> NMInitReset * enable application communication by D_Online * D_Init (...;BusAwake) -> D_online * Leave NMBusSleep -> NMInitReset * TO(TError) -> D_online * NMLimphome * enable cyclically application communication (TError) by D_Online ## D_Offline * OSEK NM 定義: * This service allows the user transmission via the data link layer at least to be blocked. * shut down the bus hardware * 對照 RH850f1l_hardware_CAN 定義: * 可能為: - [x] Channel communication mode -> Channel reset mode * 如果已經在 reset or stop mode 則不動作 - [ ] ~~Channel communication mode -> Channel halt mode~~ * 呼叫時機 * D_status.ind -> D_offline -> DInit(...;BusRestart) * NMOn -> NMInitLimphome * D_offline -> TO(Twbs) -> D_init(...;BusSleep) * NMNormalPrepSleep -> NMTwbsNormal -> NMBusSleep * D_offline -> TO(Twbs) -> D_init(...;BusSleep) * NMLimphomePrepSleep -> NMTwbsLimphome -> NMBusSleep ## OSEK NM Alarm 定義 * TTyp * typical interval between two ring messages on the bus * TMax * maximum admissible interval between two ring messages on the bus * TError * cycle time in which a node signals that an error has occurred * TWaitBusSleep * Time the NM waits before transmission in NMBusSleep * TTx * delay to repeat the transmission request of a NM message if the preceding request was rejected ## OSEK NM Alarm 呼叫情形 ### 以 Alarm Type 來做區分 * TTyp and TMax ![](https://i.imgur.com/p2J0k6R.png) ![](https://i.imgur.com/0TOExZq.png) * TTyp * NMReset -> NMrxcount <= rxlimit && NMtxcount <= tx_limit -> SetAlarm(TTyp) -> NMNormal * (OSEK NM, 46) * NMNormal -> Transmit Ring Message -> CancelAlarm(TTyp) * (OSEK NM, 48) * NMNormal -> TO(TTyp) * (OSEK NM, 48) * NMNormalPrepSleep -> TO(TTyp) -> Send ring message(NMActive == 1) -> NMNormalPrepSleep * (OSEK NM, 49) * NMNormal -> ring NMMessage receive -> NormalStandardNM -> CancelAlarm(TTyp) -> SetAlarm(TTyp)(if D == me / D = S) -> Leave NormalStandardNM * (OSEK NM, 54) * TMax * NMNormal -> Transmit Ring Message -> CancelAlarm(TMax) -> SetAlarm(TMax) * (OSEK NM, 48) * NMNormal -> TO(TTyp) -> CancelAlarm(TMax) -> SetAlarm(TMax) * (OSEK NM, 48) * NMNormal -> TO(TMax) -> NMInitReset * (OSEK NM, 48) * NMLimphome -> TO(TError) -> D_Online -> bussleep == 1 -> SetAlarm(TMax) -> Send limphome message(NMActive == 1) -> NMPrepSleep * (OSEK NM, 51) * NMLimpHomePrepSleep -> TO(TMax) at ring message -> NMInitBusSleep * (OSEK NM, 52) * NMNormal -> ring NMMessage receive -> NormalStandardNM -> CancelAlarm(TMax) -> SetAlarm(TMax)(if D != me && D != S) -> NormalStandardNM flow * (OSEK NM, 54) * TError * NMReset -> NMrxcount > rxlimit || NMtxcount > tx_limit -> SetAlarm(TError) -> NMLimphome * (OSEK NM, 46) * from bus off or normal -> SetAlarm(TError) -> NMLimphome * (OSEK NM, 46) * Leave NMLimphome -> CancelAlarm(TError) * (OSEK NM, 46) * NMLimphome -> TO(TError) -> D_Online -> bussleep != 1 -> SetAlarm(TError) -> Send limphome message(NMActive == 1) -> NMLimpHome * (OSEK NM, 51) * TwaitBusSleep * NMNormalPrepSleep -> Transmit Ring Message -> D_Offline -> SetAlarm(Twbs) -> NMTwbsNormal * (OSEK NM, 49) * Leave NMInitBusSleep -> D_Offline -> SetAlarm(Twbs) -> NMTwbsNormal * (OSEK NM, 49) * NMTwbsNormal -> TO(Twbs) -> D_Init(BusSleep) -> NMBusSleep * (OSEK NM, 50) * NMTwbsNormal -> GotoMode(Awake) -> CancelAlarm(Twbs) -> NMInitReset * (OSEK NM, 50) * NMTwbsNormal -> Receive any NM message -> sleep.ind = 0 -> CancelAlarm(Twbs) -> NMInitReset * (OSEK NM, 50) * Leave NMInitBusSleep -> D_Offline -> SetAlarm(Twbs) -> NMTwbsLimpHome * (OSEK NM, 51) * NMLimpHome -> Receive any NM message -> (state checking) -> D_Offline -> SetAlarm(Twbs) -> NMTwbsLimpHome * (OSEK NM, 51) * NMTwbsLimpHome -> GotoMode(Awake) -> CancelAlarm(Twbs) -> NMLimpHome * (OSEK NM, 53) * NMTwbsLimpHome -> Receive any NM message -> sleep.ind == 0 -> CancelAlarm(Twbs) -> NMLimpHome * (OSEK NM, 53) * NMTwbsLimpHome -> TO(Twbs) -> D_Init(BusSleep) -> NMBusSleep * (OSEK NM, 53) * TTx * NMNormal -> DLL refected the command to send actual NM message(ring/alive) -> SetAlarm(Ttx) -> NMNormal * (OSEK NM, 55) - [ ] DLL refect 目前不能傳然後 SetAlarm(Ttx)? - [ ] DLL refect Error 然後 SetAlarm(Ttx)? * NMNormal -> TO(Ttx) Send actual NMmessage(ring/alive) -> NMNormal * (OSEK NM, 55) ### SetAlarm 時機 #### TTyp * TTyp 被設置來後 TO(TTyp) 會 Send Ring Message * NMReset -> NMrxcount <= rxlimit && NMtxcount <= tx_limit -> SetAlarm(TTyp) -> NMNormal * NMReset 到 NMNormal 時會 SetAlarm(TTyp),以傳送第一筆 Ring Message * NMNormal -> ring NMMessage receive -> NormalStandardNM -> CancelAlarm(TTyp) -> SetAlarm(TTyp)(if D == me / D = S) -> Leave NormalStandardNM * 如果收到傳給自己的 Ring Message(D==me),SetAlarm(TTyp) 以傳遞 Ring Message,讓 Ring Message 在 network 循環 * 如果收到 (D==S) 的 Ring Message,代表 net 目前只有我自己這個 node,而我收到我自己傳出去的 Ring Message,這時仍然 SetAlarm(TTyp) 以傳遞 Ring Message #### TMax * NMNormal -> Transmit Ring Message -> CancelAlarm(TMax) -> SetAlarm(TMax) * 當剛剛傳送 ring message,先 Cancel(TMax) 再 Set(TMax),因為 * NMNormal -> TO(TTyp) -> CancelAlarm(TMax) -> SetAlarm(TMax) * NMLimphome -> TO(TError) -> D_Online -> bussleep == 1 -> SetAlarm(TMax) -> Send limphome message(NMActive == 1) -> NMPrepSleep * NMNormal -> ring NMMessage receive -> NormalStandardNM -> CancelAlarm(TMax) -> SetAlarm(TMax)(if D != me && D != S) -> NormalStandardNM flow ### CancelAlarm 時機 #### TTyp * NMNormal -> Transmit Ring Message -> CancelAlarm(TTyp) * 傳送 Ring Message 後 CancelAlarm(TTyp) * NMNormal -> ring NMMessage receive -> NormalStandardNM -> CancelAlarm(TTyp) -> SetAlarm(TTyp)(if D == me / D = S) -> Leave NormalStandardNM * 接收到 Ring Message 後,不論是否是給自己都先 CancelAlarm(TTyp) #### TMax * NMNormal -> Transmit Ring Message -> CancelAlarm(TMax) -> SetAlarm(TMax) * NMNormal -> TO(TTyp) -> CancelAlarm(TMax) -> SetAlarm(TMax) * NMNormal -> ring NMMessage receive -> NormalStandardNM -> CancelAlarm(TMax) -> SetAlarm(TMax)(if D != me && D != S) -> NormalStandardNM flow ## RH850/F1L 176 pins RS-CAN 設定 ### Global Initial Setting ~~* 設定 clk 資訊 * clk_xincan = MainOSC/1 (16MHz)~~ * clk 現在移到 Global Initial Setting 之前 * 確定 CAN RAM initialize is finished 才開始做 CAN 設定 * The RS-CAN module initializes the CAN RAM after the MCU is reset * The GRAMINIT flag in the RSCAN0GSTS register * is set to 1 (CAN RAM initialization is ongoing) during the RAM initialization * is cleared to 0 (CAN RAM initialization is finished) * Transition from global stop mode to global reset mode * Set GSLPR in the RSCAN0GCTR register to 0 * 設定 Global configuration: **RSCAN0GCFG** register * ITRCP[15:0] = 0 * Interval Timer Prescaler Set When these bits are set to M, the pclk is divided by M. Setting 0000H is prohibited when the interval timer is in use. * TSBTCS[2:0] = 0 * Timestamp Clock Source Select: Channel 0 bit time clock * TSSS = 0 * Timestamp Source Select: pclk/2 * TSP[3:0] = 0 * Timestamp Clock Source Division: Not divided * DCS = 1 * CAN Clock Source Select: clk_xincan * MME = 0 * Mirror function is disabled. * DRE = 0 * DLC replacement is disabled. * DCE = 1 * DLC check is enabled. * TPRI = 0 * Transmit Priority Select: ID priority * 設定 receive rule * 設定 per channel 的 Rx rule 數量 * RNCm[7:0] bits in the RSCAN0GAFLCFG0, RSCAN0GAFLCFG1 register. * Channel 0: 6 * Channel 1: 6 * Channel 3: 6 * Channel 4: 6 * 將變數 pCRE assign 成 IDRule register 的 base * pCRE = (volatile CAN_RX_RULE_TYPE *)&(RSCAN0GAFLID0) * RSCAN0GAFLID0: <RSCAN0_base> + 0500H * 允許寫入 rule table * Set the AFLDAE bit in the RSCAN0GAFLECTR register to 1 * 選擇 rule page table number, 一個 page 可以有 16 個 rules * A page number can be selected from a range of page 0 (00000B) to page 23 (10111B). * AFLPN[4:0] bits in the RSCAN0GAFLECTR register. * 將 rule 寫入 * Set receive rules by the * RSCAN0GAFLIDj register * RSCAN0GAFLMj register * RSCAN0GAFLP0j register * RSCAN0GAFLP1j register * 不允許寫入 rule table * Set the AFLDAE bit in the RSCAN0GAFLECTR register to 0 * 設置 receive buffer * RSCAN0RMNB * Set the number of receive buffers (0 to 96) by the NRXMB[7:0] bits. * 因為使用 transmit/receive FIFO buffer,所以這裡 set 為 0 * 設置 receive FIFO buffer * RSCAN0RFCCx * TODO: test if it is needed * 設置 transmit/receive FIFO buffer * RSCAN0CFCCk (k from 0 to 17, each channel has 3 buffers) * 設置 RSCAN0CFCC9 for CAN3 * 設置 RSCAN0CFCC12 for CAN4 * 0x00001103u * CFTML[3:0] = 0 * Transmit Buffer Link to buffer 0 * CFM[1:0] = 0 * Transmit/Receive FIFO Mode Select: Receive mode * CFIM = 1 * Receive mode/gateway mode * A FIFO receive interrupt request is generated each time a message has been received. * CFDC[2:0] = 1 * Transmit/Receive FIFO Buffer Depth Configuration * 4 messages * CFRXIE = 1 * Transmit/receive FIFO receive interrupt is enabled. * CFE = 1 * Transmit/receive FIFO buffers are used. * enable/disable global interrupt * RSCAN0GCTR * RSCAN0GCTR &= 0xfffff8ffu * Transmit history buffer overflow interrupt is disabled. * FIFO message lost interrupt is disabled. * DLC error interrupt is disabled. * switch to global operating mode * RSCAN0GCTR &= 0xfffffffcu; * GMDC[1:0] = 0 * Global operating mode * CAN_NM_Global_Init() in r_rscan.c ```c= /***************************************************************************** ** Function: CAN_NM_Global_Init ** Description: Initial Settings for Global CAN ** Parameter: None ** Return: None ******************************************************************************/ void CAN_NM_Global_Init(void) { protected_write(PROTCMD1, PROTS1, CKSC_ICANOSCD_CTL, 0x01u); // set clk_xincan (CKSCLK_ICANOSC) = MainOSC/1 (16MHz) while (0x01u != CKSC_ICANOSCD_ACT) { } /* Wait while CAN RAM initialization is ongoing */ while ((RSCAN0GSTS & 0x00000008u)) { } /* Switch to global/channel reset mode */ /* Global stop mode -> Global reset mode */ RSCAN0GCTR &= 0xfffffffbu; // GSLPR bit : 0 -> set as Other than global stop mode // GMDC[1:0] : 01 -> Global reset mode while ((RSCAN0GSTS & 0x04) != 0) { } // GSLPSTS : check status for global stop mode/* /* Global configuration */ RSCAN0GCFG = 0x00000012u; // DCS bit : CAN Clock Source = clk_xincan // MME bit : Mirror function is disabled // DRE bit : DLC replacement is disabled // DCE bit : DLC check is enabled // TPRI bit : Transmit Priority = ID priority /* ==== Rx rule setting ==== */ R_RSCAN0_SetRxRule(); /* ==== Buffer setting ==== */ RSCAN0RMNB = 0x00u; /* Can_SetGlobalBuffer, set 0 receive buffers */ RSCAN0RFCC0 = 0x00001101u; // An interrupt occurs each time a message has been received, Depth: 4 messages, Timing Select: FIFO 1/8 full RSCAN0CFSTS9 = 0x00000000u; //initialization RSCAN0CFCC9 = 0x00001103u; // Link to Buffer 0 CFTML[23:20], Select Receive mode CFM[17:16], Enable Transmit/Receive FIFO interrupt CFRXIE[1] Transmit/receive FIFO buffer are used /* Set THLEIE disabled, MEIE(FIFO Message Lost Interrupt disabled) */ RSCAN0GCTR &= 0xfffff8ffu; /* TODO: for global interrupt */ /* If GlobalChannel in halt or reset mode */ if (RSCAN0GSTS & 0x03u) { RSCAN0GCTR &= 0xfffffffcu; /* Switch to communication mode */ while ((RSCAN0GSTS & 0x02u) == 2u) { /* While halt mode */ } while ((RSCAN0GSTS & 0x01u) == 1u) { /* While reset mode */ } } /* Transmit/receive FIFO buffers are used. */ RSCAN0CFCC9 |= 0x00000001u; } ``` * rule table in r_can_table.h ```c= #define RX_RULE_NUM (12U) /* Rx Rule number */ #define RX_RULE_NUM_CH0 (3U) /* Channel 0 Rx rule number */ #define RX_RULE_NUM_CH1 (3U) /* Channel 1 Rx rule number */ #define RX_RULE_NUM_CH2 (0U) /* Channel 2 Rx rule number */ #define RX_RULE_NUM_CH3 (3U) /* Channel 3 Rx rule number */ #define RX_RULE_NUM_CH4 (3U) /* Channel 4 Rx rule number */ /* Structure */ typedef struct { uint32_t lword[4]; }can_cre_type; extern const can_cre_type RX_RULE_TABLE_LIST[RX_RULE_NUM]; ``` * rule table in r_can_table.c ```c= const can_cre_type RX_RULE_TABLE_LIST[RX_RULE_NUM] = { /* CAN 0 reception rules */ {{0x00000300UL, 0xDFFFFFF0UL, 0x00000000UL, 0x00020000UL}}, /* NO.000 : std data frm ID = H'1FFFFFF0~1FFFFFFF will be accepted, destination Rx FIFOBuffer0 */ {{0x00000020UL, 0xDFFFFFF0UL, 0x00008100UL, 0x00000000UL}}, /* NO.001 : std data frm ID = H'20~2F will be accepted, destination Rx Buffer1 */ {{0x00000030UL, 0xDFFFFFF0UL, 0x00008200UL, 0x00000000UL}}, /* NO.002 : std data frm ID = H'30~3F will be accepted, destination Rx Buffer2 */ /* CAN 1 reception rules */ {{0x00000300UL, 0xDFFFFFF0UL, 0x00000000UL, 0x00020000UL}}, /* NO.000 : std data frm ID = H'1FFFFFF0~1FFFFFFF will be accepted, destination Rx FIFOBuffer0 */ {{0x00000020UL, 0xDFFFFFF0UL, 0x00008100UL, 0x00000000UL}}, /* NO.001 : std data frm ID = H'20~2F will be accepted, destination Rx Buffer1 */ {{0x00000030UL, 0xDFFFFFF0UL, 0x00008200UL, 0x00000000UL}}, /* NO.002 : std data frm ID = H'30~3F will be accepted, destination Rx Buffer2 */ /* CAN 3 reception rules */ {{0x00000300UL, 0xDFFFFFF0UL, 0x00000000UL, 0x00020000UL}}, /* NO.000 : std data frm ID = H'1FFFFFF0~1FFFFFFF will be accepted, destination Rx FIFOBuffer0 */ {{0x00000020UL, 0xDFFFFFF0UL, 0x00008100UL, 0x00000000UL}}, /* NO.001 : std data frm ID = H'20~2F will be accepted, destination Rx Buffer1 */ {{0x00000030UL, 0xDFFFFFF0UL, 0x00008200UL, 0x00000000UL}}, /* NO.002 : std data frm ID = H'30~3F will be accepted, destination Rx Buffer2 */ /* CAN 4 reception rules */ {{0x00000010UL, 0xDFFFFFF0UL, 0x00008600UL, 0x00000000UL}}, /* NO.000 : std data frm ID = H'10~1F will be accepted, destination Rx Buffer6 */ {{0x00000020UL, 0xDFFFFFF0UL, 0x00008700UL, 0x00000000UL}}, /* NO.001 : std data frm ID = H'20~2F will be accepted, destination Rx Buffer7 */ {{0x00000030UL, 0xDFFFFFF0UL, 0x00008800UL, 0x00000000UL}}, /* NO.002 : std data frm ID = H'30~3F will be accepted, destination Rx Buffer8 */ }; ``` * R_RSCAN0_SetRxRule() in r_rscan.c ```c= /***************************************************************************** ** Function: Can_SetRxRule ** Description: Set all Rx rules ** Parameter: None ** Return: None ******************************************************************************/ static void R_RSCAN0_SetRxRule(void) { uint16_t RxRuleIdx; uint8_t PageRxRuleIdx; volatile CAN_RX_RULE_TYPE *pCRE; /* Set Rx rule number per channel */ RSCAN0GAFLCFG0 |= 0x06060006u; /* Channel 0,1,3 rule numbers are 6 */ RSCAN0GAFLCFG1 |= 0x06000000u; /* Channel4 rule numbers are 6 */ /* Get access base address of Rx rule */ pCRE = (volatile CAN_RX_RULE_TYPE *)&(RSCAN0GAFLID0); /* Receive Rule Table Write Enable */ RSCAN0GAFLECTR |= 0x00000100u; /* Copy Rx rule one by one */ for (RxRuleIdx = 0U; RxRuleIdx < CAN_RX_RULE_NUM; RxRuleIdx++) { PageRxRuleIdx = (uint8_t)(RxRuleIdx & CAN_PAGE_RX_RULE_IDX_MASK); /* Update target Rx rule page if necessary */ /* Receive Rule Table Page Number Configuration */ if (PageRxRuleIdx == 0U) { /* set page number, range from 0 to 23 */ RSCAN0GAFLECTR |= RxRuleIdx >> CAN_RX_RULE_PAGE_IDX_BIT_POS; } /* Set a single Rx rule.*/ pCRE[PageRxRuleIdx] = CAN_RX_RULE_TABLE[RxRuleIdx]; } /* Rx rule write disable */ RSCAN0GAFLECTR &= 0xfffffeffu; } ```