|
- /*
- MIT License
-
- Copyright (c) 2018 Antonio Alexander Brewer (tonton81) - https://github.com/tonton81
-
- Designed and tested for PJRC Teensy 4.0.
-
- Forum link : https://forum.pjrc.com/threads/56035-FlexCAN_T4-FlexCAN-for-Teensy-4?highlight=flexcan_t4
-
- Thanks goes to skpang, mjs513, and collin for tech/testing support
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
- #include <FlexCAN_T4.h>
- #include "imxrt_flexcan.h"
- #include "Arduino.h"
-
- #if defined(__IMXRT1062__)
- static void flexcan_isr_can3();
- static void flexcan_isr_can2();
- static void flexcan_isr_can1();
- #endif
- #if defined(__MK20DX256__) || defined(__MK64FX512__)
- static void flexcan_isr_can0();
- #endif
- #if defined(__MK66FX1M0__)
- static void flexcan_isr_can0();
- static void flexcan_isr_can1();
- #endif
-
- FCTP_FUNC FCTP_OPT::FlexCAN_T4() {
- #if defined(__IMXRT1062__)
- if ( _bus == CAN3 ) _CAN3 = this;
- if ( _bus == CAN2 ) _CAN2 = this;
- if ( _bus == CAN1 ) _CAN1 = this;
- #endif
- #if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
- if ( _bus == CAN1 ) _CAN1 = this;
- if ( _bus == CAN0 ) _CAN0 = this;
- #endif
- }
-
- #if defined(__IMXRT1062__)
- FCTP_FUNC void FCTP_OPT::setClock(FLEXCAN_CLOCK clock) {
- if ( clock == CLK_OFF ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(3) | CCM_CSCMR2_CAN_CLK_PODF(0);
- if ( clock == CLK_8MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(2) | CCM_CSCMR2_CAN_CLK_PODF(9);
- if ( clock == CLK_16MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(2) | CCM_CSCMR2_CAN_CLK_PODF(4);
- if ( clock == CLK_24MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(1) | CCM_CSCMR2_CAN_CLK_PODF(0);
- if ( clock == CLK_20MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(2) | CCM_CSCMR2_CAN_CLK_PODF(3);
- if ( clock == CLK_30MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(0) | CCM_CSCMR2_CAN_CLK_PODF(1);
- if ( clock == CLK_40MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(2) | CCM_CSCMR2_CAN_CLK_PODF(1);
- if ( clock == CLK_60MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(0) | CCM_CSCMR2_CAN_CLK_PODF(0);
- if ( clock == CLK_80MHz ) CCM_CSCMR2 = (CCM_CSCMR2 & 0xFFFFFC03) | CCM_CSCMR2_CAN_CLK_SEL(2) | CCM_CSCMR2_CAN_CLK_PODF(0);
-
- if ( _CAN1 ) _CAN1->setBaudRate(currentBitrate, (( FLEXCANb_CTRL1(_bus) & FLEXCAN_CTRL_LOM ) ? LISTEN_ONLY : TX));
- if ( _CAN2 ) _CAN2->setBaudRate(currentBitrate, (( FLEXCANb_CTRL1(_bus) & FLEXCAN_CTRL_LOM ) ? LISTEN_ONLY : TX));
- if ( _CAN3 ) _CAN3->setBaudRate(currentBitrate, (( FLEXCANb_CTRL1(_bus) & FLEXCAN_CTRL_LOM ) ? LISTEN_ONLY : TX));
- }
-
- FCTP_FUNC uint32_t FCTP_OPT::getClock() {
- const uint8_t clocksrc[4] = {60, 24, 80, 0};
- return clocksrc[(CCM_CSCMR2 & 0x300) >> 8];
- }
- #endif
-
- FCTP_FUNC void FCTP_OPT::begin() {
- #if defined(__IMXRT1062__)
- if ( !getClock() ) setClock(CLK_24MHz); /* no clock enabled, enable osc clock */
-
- if ( _bus == CAN3 ) {
- nvicIrq = IRQ_CAN3;
- _VectorsRam[16 + nvicIrq] = flexcan_isr_can3;
- CCM_CCGR7 |= 0x3C0;
- busNumber = 3;
- }
- if ( _bus == CAN2 ) {
- nvicIrq = IRQ_CAN2;
- _VectorsRam[16 + nvicIrq] = flexcan_isr_can2;
- CCM_CCGR0 |= 0x3C0000;
- busNumber = 2;
- }
- if ( _bus == CAN1 ) {
- nvicIrq = IRQ_CAN1;
- _VectorsRam[16 + nvicIrq] = flexcan_isr_can1;
- CCM_CCGR0 |= 0x3C000;
- busNumber = 1;
- }
- #endif
-
-
-
- #if defined(__MK20DX256__)
- if ( _bus == CAN0 ) {
- nvicIrq = IRQ_CAN_MESSAGE;
- _VectorsRam[16 + nvicIrq] = flexcan_isr_can0;
- busNumber = 0;
- }
- #endif
-
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- if ( _bus == CAN0 ) {
- nvicIrq = IRQ_CAN0_MESSAGE;
- _VectorsRam[16 + nvicIrq] = flexcan_isr_can0;
- busNumber = 0;
- }
- #endif
-
- #if defined(__MK66FX1M0__)
- else if ( _bus == CAN1 ) {
- nvicIrq = IRQ_CAN1_MESSAGE;
- _VectorsRam[16 + nvicIrq] = flexcan_isr_can1;
- busNumber = 1;
- }
- #endif
-
- #if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
- OSC0_CR |= OSC_ERCLKEN;
- if ( _bus == CAN0 ) SIM_SCGC6 |= SIM_SCGC6_FLEXCAN0;
- #if defined(__MK66FX1M0__)
- else if ( _bus == CAN1 ) SIM_SCGC3 |= SIM_SCGC3_FLEXCAN1;
- #endif
- FLEXCANb_CTRL1(_bus) &= ~FLEXCAN_CTRL_CLK_SRC;
- #endif
-
- setTX(); setRX();
-
- FLEXCANb_MCR(_bus) &= ~FLEXCAN_MCR_MDIS; /* enable module */
- FLEXCAN_EnterFreezeMode();
- FLEXCANb_CTRL1(_bus) |= FLEXCAN_CTRL_LOM; /* listen only mode */
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_FRZ; /* enable freeze bit */
- while (FLEXCANb_MCR(_bus) & FLEXCAN_MCR_LPM_ACK);
- softReset(); /* reset bus */
- while (!(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK));
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_SRX_DIS; /* Disable self-reception */
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_IRMQ; // individual mailbox masking
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_AEN; // TX ABORT FEATURE
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_LPRIO_EN; // TX PRIORITY FEATURE
- FLEXCANb_MCR(_bus) &= ~0x8800; // disable DMA and FD (valid bits are reserved in legacy controllers)
- FLEXCANb_CTRL2(_bus) |= FLEXCAN_CTRL2_RRS | // store remote frames
- FLEXCAN_CTRL2_EACEN | /* handles the way filtering works. Library adjusts to whether you use this or not */
- FLEXCAN_CTRL2_MRP; // mailbox > FIFO priority.
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_WRN_EN;
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_WAK_MSK;
-
- disableFIFO(); /* clears all data and layout to legacy mailbox mode */
- FLEXCAN_ExitFreezeMode();
- NVIC_ENABLE_IRQ(nvicIrq);
- }
-
- FCTP_FUNC void FCTP_OPT::enableFIFO(bool status) {
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- FLEXCANb_MCR(_bus) &= ~FLEXCAN_MCR_FEN; // Disable FIFO if already enabled for cleanup.
- writeIMASK(0ULL); // disable all FIFO/MB Interrupts
-
- for (uint8_t i = 0; i < FLEXCANb_MAXMB_SIZE(_bus); i++ ) { // clear all mailboxes
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (i * 0x10)));
- mbxAddr[0] = mbxAddr[1] = mbxAddr[2] = mbxAddr[3] = 0; // code, id, word0, word1
- FLEXCANb_RXIMR(_bus, i) = 0UL; // CLEAR MAILBOX MASKS (RXIMR)
- }
-
- FLEXCANb_RXMGMASK(_bus) = FLEXCANb_RXFGMASK(_bus) = 0;
- writeIFLAG(readIFLAG()); // (all bits reset when written back)
-
- if ( status ) {
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_FEN;
- for (uint8_t i = mailboxOffset(); i < FLEXCANb_MAXMB_SIZE(_bus); i++) FLEXCANb_MBn_CS(_bus,i) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
- }
- else { // FIFO disabled default setup of mailboxes, 0-7 RX, 8-15 TX
- for (uint8_t i = 0; i < FLEXCANb_MAXMB_SIZE(_bus); i++ ) { // clear all mailboxes
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (i * 0x10)));
- if ( i < (FLEXCANb_MAXMB_SIZE(_bus) / 2) ) {
- mbxAddr[0] = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY) | ((i < (FLEXCANb_MAXMB_SIZE(_bus) / 4)) ? 0 : FLEXCAN_MB_CS_IDE | FLEXCAN_MB_CS_SRR);
- FLEXCANb_RXIMR(_bus, i) = 0UL | ((FLEXCANb_CTRL2(_bus) & FLEXCAN_CTRL2_EACEN) ? (1UL << 30) : 0); // (RXIMR)
- }
- else {
- mbxAddr[0] = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
- }
- }
- }
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::enableFIFOInterrupt(bool status) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN) ) return; /* FIFO must be enabled first */
- if ( FLEXCANb_IMASK1(_bus) & FLEXCAN_IMASK1_BUF5M ) return; /* FIFO interrupts already enabled */
- FLEXCANb_IMASK1(_bus) &= ~0xFF; /* disable FIFO interrupt flags */
- if ( status ) FLEXCANb_IMASK1(_bus) |= FLEXCAN_IMASK1_BUF5M; /* enable FIFO interrupt */
- }
-
- FCTP_FUNC void FCTP_OPT::enableMBInterrupts(bool status) {
- FLEXCAN_EnterFreezeMode();
- for ( uint8_t mb_num = mailboxOffset(); mb_num < FLEXCANb_MAXMB_SIZE(_bus); mb_num++ ) {
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) continue; // skip TX mailboxes
- enableMBInterrupt((FLEXCAN_MAILBOX)mb_num, status);
- }
- FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::enableMBInterrupt(const FLEXCAN_MAILBOX &mb_num, bool status) {
- if ( mb_num < mailboxOffset() ) return; /* mailbox not available */
- if ( status ) writeIMASKBit(mb_num); /* enable mailbox interrupt */
- else writeIMASKBit(mb_num, 0); /* disable mailbox interrupt */
- }
-
- FCTP_FUNC bool FCTP_OPT::setMB(const FLEXCAN_MAILBOX &mb_num, const FLEXCAN_RXTX &mb_rx_tx, const FLEXCAN_IDE &ide) {
- if ( mb_num < mailboxOffset() ) return 0; /* mailbox not available */
- writeIMASKBit(mb_num, 0); /* immediately disable mailbox interrupt */
- FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)); // Reading Control Status atomically locks mailbox (if it is RX mode).
- FLEXCANb_MBn_ID(_bus, mb_num) = 0UL;
- FLEXCANb_MBn_WORD0(_bus, mb_num) = 0UL;
- FLEXCANb_MBn_WORD1(_bus, mb_num) = 0UL;
- if ( mb_rx_tx == RX ) {
- if ( ide != EXT ) FLEXCANb_MBn_CS(_bus, mb_num) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY);
- else FLEXCANb_MBn_CS(_bus, mb_num) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY) | FLEXCAN_MB_CS_SRR | FLEXCAN_MB_CS_IDE;
- }
- if ( mb_rx_tx == TX ) {
- FLEXCANb_MBn_CS(_bus, mb_num) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
- }
- if ( ide == INACTIVE ) {
- FLEXCANb_MBn_CS(_bus, mb_num) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_INACTIVE);
- }
- (void)FLEXCANb_TIMER(_bus);
- writeIFLAGBit(mb_num); /* clear mailbox reception flag */
- mb_filter_table[mb_num][0] = ( ((FLEXCANb_MBn_CS(_bus, mb_num) & 0x600000) ? 1UL : 0UL) << 27); /* extended flag check */
- return 1;
- }
-
- FCTP_FUNC void FCTP_OPT::mailboxStatus() {
- if ( FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN ) {
- Serial.print("FIFO Enabled --> "); ( FLEXCANb_IMASK1(_bus) & FLEXCAN_IFLAG1_BUF5I ) ? Serial.println("Interrupt Enabled") : Serial.println("Interrupt Disabled");
- Serial.print("\tFIFO Filters in use: ");
- uint32_t remaining_mailboxes = FLEXCANb_MAXMB_SIZE(_bus) - 6 /* MAXMB - FIFO */ - ((((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 2);
- if ( FLEXCANb_MAXMB_SIZE(_bus) < (6 + ((((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 2))) remaining_mailboxes = 0;
- Serial.println(constrain((uint8_t)(FLEXCANb_MAXMB_SIZE(_bus) - remaining_mailboxes), 0, 32));
- Serial.print("\tRemaining Mailboxes: ");
- if ( FLEXCANb_MAXMB_SIZE(_bus) < (6 + ((((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 2))) remaining_mailboxes = 0;
- Serial.println(remaining_mailboxes); // 8 filters per 2 mailboxes
- for ( uint8_t i = FLEXCANb_MAXMB_SIZE(_bus) - remaining_mailboxes; i < FLEXCANb_MAXMB_SIZE(_bus); i++ ) {
- switch ( FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, i)) ) {
- case 0b0000: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_INACTIVE"); break;
- }
- case 0b0100: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.print(" code: RX_EMPTY");
- (FLEXCANb_MBn_CS(_bus, i) & FLEXCAN_MB_CS_IDE) ? Serial.println("\t(Extended Frame)") : Serial.println("\t(Standard Frame)");
- break;
- }
- case 0b0010: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_FULL"); break;
- }
- case 0b0110: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_OVERRUN"); break;
- }
- case 0b1010: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_RANSWER"); break;
- }
- case 0b0001: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_BUSY"); break;
- }
- case 0b1000: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: TX_INACTIVE"); break;
- }
- case 0b1001: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: TX_ABORT"); break;
- }
- case 0b1100: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.print(" code: TX_DATA (Transmitting)");
- uint32_t extid = (FLEXCANb_MBn_CS(_bus, i) & FLEXCAN_MB_CS_IDE);
- (extid) ? Serial.print("(Extended Frame)") : Serial.print("(Standard Frame)");
- uint32_t dataIn = FLEXCANb_MBn_WORD0(_bus, i);
- uint32_t id = (FLEXCANb_MBn_ID(_bus, i) & FLEXCAN_MB_ID_EXT_MASK);
- if (!extid) id >>= FLEXCAN_MB_ID_STD_BIT_NO;
- Serial.print("(ID: 0x"); Serial.print(id, HEX); Serial.print(")");
- Serial.print("(Payload: "); Serial.print((uint8_t)(dataIn >> 24), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 16), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 8), HEX);
- Serial.print(" "); Serial.print((uint8_t)dataIn, HEX);
- dataIn = FLEXCANb_MBn_WORD1(_bus, i);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 24), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 16), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 8), HEX);
- Serial.print(" "); Serial.print((uint8_t)dataIn, HEX);
- Serial.println(")");
- break;
- }
- case 0b1110: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: TX_TANSWER"); break;
- }
- }
- } // for loop
- return;
- } // fifo detected ends here
-
- Serial.print("FIFO Disabled\n\tMailboxes:\n");
- for ( uint8_t i = 0; i < FLEXCANb_MAXMB_SIZE(_bus); i++ ) {
- switch ( FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, i)) ) {
- case 0b0000: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_INACTIVE"); break;
- }
- case 0b0100: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.print(" code: RX_EMPTY");
- (FLEXCANb_MBn_CS(_bus, i) & FLEXCAN_MB_CS_IDE) ? Serial.println("\t(Extended Frame)") : Serial.println("\t(Standard Frame)");
- break;
- }
- case 0b0010: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_FULL"); break;
- }
- case 0b0110: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_OVERRUN"); break;
- }
- case 0b1010: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_RANSWER"); break;
- }
- case 0b0001: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: RX_BUSY"); break;
- }
- case 0b1000: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: TX_INACTIVE"); break;
- }
- case 0b1001: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: TX_ABORT"); break;
- }
- case 0b1100: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.print(" code: TX_DATA (Transmitting)");
- uint32_t extid = (FLEXCANb_MBn_CS(_bus, i) & FLEXCAN_MB_CS_IDE);
- (extid) ? Serial.print("(Extended Frame)") : Serial.print("(Standard Frame)");
- uint32_t dataIn = FLEXCANb_MBn_WORD0(_bus, i);
- uint32_t id = (FLEXCANb_MBn_ID(_bus, i) & FLEXCAN_MB_ID_EXT_MASK);
- if (!extid) id >>= FLEXCAN_MB_ID_STD_BIT_NO;
- Serial.print("(ID: 0x"); Serial.print(id, HEX); Serial.print(")");
- Serial.print("(Payload: "); Serial.print((uint8_t)(dataIn >> 24), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 16), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 8), HEX);
- Serial.print(" "); Serial.print((uint8_t)dataIn, HEX);
- dataIn = FLEXCANb_MBn_WORD1(_bus, i);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 24), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 16), HEX);
- Serial.print(" "); Serial.print((uint8_t)(dataIn >> 8), HEX);
- Serial.print(" "); Serial.print((uint8_t)dataIn, HEX);
- Serial.println(")");
- break;
- }
- case 0b1110: {
- Serial.print("\t\tMB"); Serial.print(i); Serial.println(" code: TX_TANSWER"); break;
- }
- }
- } // for loop
- }
-
- FCTP_FUNC uint64_t FCTP_OPT::readIFLAG() {
- #if defined(__IMXRT1062__)
- return (((uint64_t)FLEXCANb_IFLAG2(_bus) << 32) | FLEXCANb_IFLAG1(_bus));
- #endif
- return FLEXCANb_IFLAG1(_bus);
- }
-
- FCTP_FUNC void FCTP_OPT::writeIFLAG(uint64_t value) {
- #if defined(__IMXRT1062__)
- FLEXCANb_IFLAG2(_bus) = value >> 32;
- #endif
- FLEXCANb_IFLAG1(_bus) = value;
- }
-
- FCTP_FUNC void FCTP_OPT::writeIFLAGBit(uint8_t mb_num) {
- if ( mb_num < 32 ) FLEXCANb_IFLAG1(_bus) |= (1UL << mb_num);
- else FLEXCANb_IFLAG2(_bus) |= (1UL << (mb_num - 32));
- }
-
- FCTP_FUNC void FCTP_OPT::writeIMASK(uint64_t value) {
- #if defined(__IMXRT1062__)
- FLEXCANb_IMASK2(_bus) = value >> 32;
- #endif
- FLEXCANb_IMASK1(_bus) = value;
- }
-
- FCTP_FUNC uint64_t FCTP_OPT::readIMASK() {
- #if defined(__IMXRT1062__)
- return (((uint64_t)FLEXCANb_IMASK2(_bus) << 32) | FLEXCANb_IMASK1(_bus));
- #endif
- return FLEXCANb_IMASK1(_bus);
- }
-
- FCTP_FUNC void FCTP_OPT::writeIMASKBit(uint8_t mb_num, bool set) {
- if ( mb_num < 32 ) (( set ) ? FLEXCANb_IMASK1(_bus) |= (1UL << mb_num) : FLEXCANb_IMASK1(_bus) &= ~(1UL << mb_num));
- else (( set ) ? FLEXCANb_IMASK2(_bus) |= (1UL << (mb_num - 32)) : FLEXCANb_IMASK2(_bus) &= ~(1UL << (mb_num - 32)));
- }
-
- FCTP_FUNC void FCTP_OPT::writeTxMailbox(uint8_t mb_num, const CAN_message_t &msg) {
- writeIFLAGBit(mb_num);
- uint32_t code = 0;
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (mb_num * 0x10)));
- mbxAddr[0] = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
- mbxAddr[1] = (( msg.flags.extended ) ? ( msg.id & FLEXCAN_MB_ID_EXT_MASK ) : FLEXCAN_MB_ID_IDSTD(msg.id));
- if ( msg.flags.remote ) code |= (1UL << 20);
- if ( msg.flags.extended ) code |= (3UL << 21);
- for ( uint8_t i = 0; i < (8 >> 2); i++ ) mbxAddr[2 + i] = (msg.buf[0 + i * 4] << 24) | (msg.buf[1 + i * 4] << 16) | (msg.buf[2 + i * 4] << 8) | msg.buf[3 + i * 4];
- code |= msg.len << 16;
- mbxAddr[0] = code | FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE);
-
- if ( msg.flags.remote ) {
- uint32_t timeout = millis();
- while ( !(readIFLAG() & (1ULL << mb_num)) && (millis() - timeout < 20) );
- writeIFLAGBit(mb_num);
- mbxAddr[0] = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE);
- }
- }
-
- FCTP_FUNC uint8_t FCTP_OPT::mailboxOffset() {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN ) ) return 0; /* return offset 0 since FIFO is disabled */
- uint32_t remaining_mailboxes = FLEXCANb_MAXMB_SIZE(_bus) - 6 /* MAXMB - FIFO */ - ((((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 2);
- if ( FLEXCANb_MAXMB_SIZE(_bus) < (6 + ((((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 2))) remaining_mailboxes = 0;
- return (FLEXCANb_MAXMB_SIZE(_bus) - remaining_mailboxes); /* otherwise return offset MB position after FIFO area */
- }
-
- FCTP_FUNC void FCTP_OPT::setMaxMB(uint8_t last) {
- last = constrain(last,1,64);
- last--;
- FLEXCAN_EnterFreezeMode();
- bool fifo_was_cleared = FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN;
- disableFIFO();
- writeIFLAG(readIFLAG()); // (all bits reset when written back) (needed for MAXMB changes)
- FLEXCANb_MCR(_bus) &= ~0x7F; // clear current value
- FLEXCANb_MCR(_bus) |= last; // set mailbox max
- if ( fifo_was_cleared ) enableFIFO();
- FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::softReset() {
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_SOFT_RST;
- while (FLEXCANb_MCR(_bus) & FLEXCAN_MCR_SOFT_RST);
- }
-
- FCTP_FUNC void FCTP_OPT::FLEXCAN_ExitFreezeMode() {
- FLEXCANb_MCR(_bus) &= ~FLEXCAN_MCR_HALT;
- while (FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- }
-
- FCTP_FUNC void FCTP_OPT::FLEXCAN_EnterFreezeMode() {
- FLEXCANb_MCR(_bus) |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT;
- while (!(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK));
- }
-
- FCTP_FUNC void FCTP_OPT::setBaudRate(uint32_t baud, FLEXCAN_RXTX listen_only) {
- currentBitrate = baud;
-
- #if defined(__IMXRT1062__)
- uint32_t clockFreq = getClock() * 1000000;
- #else
- uint32_t clockFreq = 16000000;
- #endif
-
- uint32_t divisor = 0, bestDivisor = 0, result = clockFreq / baud / (divisor + 1);
- int error = baud - (clockFreq / (result * (divisor + 1))), bestError = error;
-
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
-
- while (result > 5) {
- divisor++;
- result = clockFreq / baud / (divisor + 1);
- if (result <= 25) {
- error = baud - (clockFreq / (result * (divisor + 1)));
- if (error < 0) error *= -1;
- if (error < bestError) {
- bestError = error;
- bestDivisor = divisor;
- }
- if ((error == bestError) && (result > 11) && (result < 19)) {
- bestError = error;
- bestDivisor = divisor;
- }
- }
- }
-
- divisor = bestDivisor;
- result = clockFreq / baud / (divisor + 1);
-
- if ((result < 5) || (result > 25) || (bestError > 300)) {
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- return;
- }
-
- result -= 5; // the bitTimingTable is offset by 5 since there was no reason to store bit timings for invalid numbers
- uint8_t bitTimingTable[21][3] = {
- {0, 0, 1}, //5
- {1, 0, 1}, //6
- {1, 1, 1}, //7
- {2, 1, 1}, //8
- {2, 2, 1}, //9
- {2, 3, 1}, //10
- {2, 3, 2}, //11
- {2, 4, 2}, //12
- {2, 5, 2}, //13
- {2, 5, 3}, //14
- {2, 6, 3}, //15
- {2, 7, 3}, //16
- {2, 7, 4}, //17
- {3, 7, 4}, //18
- {3, 7, 5}, //19
- {4, 7, 5}, //20
- {4, 7, 6}, //21
- {5, 7, 6}, //22
- {6, 7, 6}, //23
- {6, 7, 7}, //24
- {7, 7, 7}, //25
- }, propSeg = bitTimingTable[result][0], pSeg1 = bitTimingTable[result][1], pSeg2 = bitTimingTable[result][2];
- FLEXCANb_CTRL1(_bus) = (FLEXCAN_CTRL_PROPSEG(propSeg) | FLEXCAN_CTRL_RJW(1) | FLEXCAN_CTRL_PSEG1(pSeg1) |
- FLEXCAN_CTRL_PSEG2(pSeg2) | FLEXCAN_CTRL_ERR_MSK | FLEXCAN_CTRL_PRESDIV(divisor));
- ( listen_only != LISTEN_ONLY ) ? FLEXCANb_CTRL1(_bus) &= ~FLEXCAN_CTRL_LOM : FLEXCANb_CTRL1(_bus) |= FLEXCAN_CTRL_LOM; /* listen-only mode */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::setMRP(bool mrp) { /* mailbox priority (1) or FIFO priority (0) */
- FLEXCAN_EnterFreezeMode();
- if ( mrp ) FLEXCANb_CTRL2(_bus) |= FLEXCAN_CTRL2_MRP;
- else FLEXCANb_CTRL2(_bus) &= ~FLEXCAN_CTRL2_MRP;
- FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::setRRS(bool rrs) { /* store remote frames */
- FLEXCAN_EnterFreezeMode();
- if ( rrs ) FLEXCANb_CTRL2(_bus) |= FLEXCAN_CTRL2_RRS;
- else FLEXCANb_CTRL2(_bus) &= ~FLEXCAN_CTRL2_RRS;
- FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::setTX(FLEXCAN_PINS pin) {
- #if defined(__IMXRT1062__)
- if ( _bus == CAN3 ) {
- if ( pin == DEF ) {
- IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_36 = 0x19; // pin31 T3B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_36 = 0x10B0; // pin31 T3B2
- }
- }
- if ( _bus == CAN2 ) {
- if ( pin == DEF ) {
- IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_02 = 0x10; // pin 1 T4B1+B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_02 = 0x10B0; // pin 1 T4B1+B2
- }
- }
- if ( _bus == CAN1 ) {
- if ( pin == DEF ) {
- IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_08 = 0x12; // pin 22 T4B1+B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08 = 0x10B0; // pin 22 T4B1+B2
- }
- if ( pin == ALT ) {
- IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_02 = 0x12; // pin 11 T4B1+B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_02= 0x10B0; // pin 11 T4B1+B2
- }
- }
- #endif
-
- #if defined(__MK20DX256__)
- CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
- #endif
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- if ( _bus == CAN0 ) {
- if ( pin == ALT ) {
- CORE_PIN3_CONFIG = 0; CORE_PIN29_CONFIG = PORT_PCR_MUX(2);
- }
- else if ( pin == DEF ) {
- CORE_PIN29_CONFIG = 0; CORE_PIN3_CONFIG = PORT_PCR_MUX(2);
- }
- } /* Alternative CAN1 pins are not broken out on Teensy 3.6 */
- #endif
- #if defined(__MK66FX1M0__)
- if ( _bus == CAN1 ) {
- CORE_PIN33_CONFIG = PORT_PCR_MUX(2);
- }
- #endif
-
- }
-
- FCTP_FUNC void FCTP_OPT::setRX(FLEXCAN_PINS pin) {
- #if defined(__IMXRT1062__)
- /* DAISY REGISTER CAN3
- 00 GPIO_EMC_37_ALT9 — Selecting Pad: GPIO_EMC_37 for Mode: ALT9
- 01 GPIO_AD_B0_15_ALT8 — Selecting Pad: GPIO_AD_B0_15 for Mode: ALT8
- 10 GPIO_AD_B0_11_ALT8 — Selecting Pad: GPIO_AD_B0_11 for Mode: ALT8
- */
- /* DAISY REGISTER CAN2
- 00 GPIO_EMC_10_ALT3 — Selecting Pad: GPIO_EMC_10 for Mode: ALT3
- 01 GPIO_AD_B0_03_ALT0 — Selecting Pad: GPIO_AD_B0_03 for Mode: ALT0
- 10 GPIO_AD_B0_15_ALT6 — Selecting Pad: GPIO_AD_B0_15 for Mode: ALT6
- 11 GPIO_B1_09_ALT6 — Selecting Pad: GPIO_B1_09 for Mode: ALT6
- */
- /* DAISY REGISTER CAN1
- 00 GPIO_SD_B1_03_ALT4 — Selecting Pad: GPIO_SD_B1_03 for Mode: ALT4
- 01 GPIO_EMC_18_ALT3 — Selecting Pad: GPIO_EMC_18 for Mode: ALT3
- 10 GPIO_AD_B1_09_ALT2 — Selecting Pad: GPIO_AD_B1_09 for Mode: ALT2
- 11 GPIO_B0_03_ALT2 — Selecting Pad: GPIO_B0_03 for Mode: ALT2
- */
- if ( _bus == CAN3 ) {
- if ( pin == DEF ) {
- IOMUXC_CANFD_IPP_IND_CANRX_SELECT_INPUT = 0x00;
- IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_37 = 0x19; // pin30 T3B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_37 = 0x10B0; // pin30 T3B2
- }
- }
- if ( _bus == CAN2 ) {
- if ( pin == DEF ) {
- IOMUXC_FLEXCAN2_RX_SELECT_INPUT = 0x01;
- IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_03 = 0x10; // pin 0 T4B1+B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_03 = 0x10B0; // pin 0 T4B1+B2
- }
- }
- if ( _bus == CAN1 ) {
- if ( pin == DEF ) {
- IOMUXC_FLEXCAN1_RX_SELECT_INPUT = 0x02;
- IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_09 = 0x12; // pin 23 T4B1+B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09 = 0x10B0; // pin 23 T4B1+B2
- }
- if ( pin == ALT ) {
- IOMUXC_FLEXCAN1_RX_SELECT_INPUT = 0x03;
- IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 0x12; // pin 13 T4B1+B2
- IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = 0x10B0; // pin 13 T4B1+B2
- }
- }
- #endif
-
- #if defined(__MK20DX256__)
- CORE_PIN4_CONFIG = PORT_PCR_MUX(2);
- #endif
- #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
- if ( _bus == CAN0 ) {
- if ( pin == ALT ) {
- CORE_PIN4_CONFIG = 0; CORE_PIN30_CONFIG = PORT_PCR_MUX(2);
- }
- else if ( pin == DEF ) {
- CORE_PIN30_CONFIG = 0; CORE_PIN4_CONFIG = PORT_PCR_MUX(2);
- }
- } /* Alternative CAN1 pins are not broken out on Teensy 3.6 */
- #endif
- #if defined(__MK66FX1M0__)
- if ( _bus == CAN1 ) {
- CORE_PIN34_CONFIG = PORT_PCR_MUX(2);
- }
- #endif
-
- }
-
- FCTP_FUNC void FCTP_OPT::setMBFilterProcessing(FLEXCAN_MAILBOX mb_num, uint32_t filter_id, uint32_t calculated_mask) {
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- FLEXCANb_RXIMR(_bus, mb_num) = calculated_mask | ((FLEXCANb_CTRL2(_bus) & FLEXCAN_CTRL2_EACEN) ? (1UL << 30) : 0);
- FLEXCANb_MBn_ID(_bus, mb_num) = ((!(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE)) ? FLEXCAN_MB_ID_IDSTD(filter_id) : FLEXCAN_MB_ID_IDEXT(filter_id));
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::setMBFilter(FLEXCAN_FLTEN input) {
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- for (uint8_t i = mailboxOffset(); i < FLEXCANb_MAXMB_SIZE(_bus); i++) {
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, i)) >> 3) ) continue; /* skip TX mailboxes */
- if ( input == ACCEPT_ALL ) FLEXCANb_RXIMR(_bus, i) = 0UL | ((FLEXCANb_CTRL2(_bus) & FLEXCAN_CTRL2_EACEN) ? (1UL << 30) : 0); // (RXIMR)
- if ( input == REJECT_ALL ) FLEXCANb_RXIMR(_bus, i) = ~0UL; // (RXIMR)
- FLEXCANb_MBn_ID(_bus, i) = ~0UL;
- mb_filter_table[i][0] = ( ((FLEXCANb_MBn_CS(_bus, i) & 0x600000) ? 1UL : 0UL) << 27); /* extended flag check */
- }
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::setMBFilter(FLEXCAN_MAILBOX mb_num, FLEXCAN_FLTEN input) {
- if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return; /* mailbox not available */
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return; /* exit on TX mailbox */
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- if ( input == ACCEPT_ALL ) FLEXCANb_RXIMR(_bus, mb_num) = 0UL | ((FLEXCANb_CTRL2(_bus) & FLEXCAN_CTRL2_EACEN) ? (1UL << 30) : 0); // (RXIMR)
- if ( input == REJECT_ALL ) FLEXCANb_RXIMR(_bus, mb_num) = ~0UL; // (RXIMR)
- FLEXCANb_MBn_ID(_bus, mb_num) = 0UL;
- mb_filter_table[mb_num][0] = ( ((FLEXCANb_MBn_CS(_bus, mb_num) & 0x600000) ? 1UL : 0UL) << 27); /* extended flag check */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC bool FCTP_OPT::setMBFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1) {
- if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return 0; /* mailbox not available */
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return 0; /* exit on TX mailbox */
- uint32_t mask = ( !(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE) ) ? FLEXCAN_MB_ID_IDSTD(((id1) ^ (id1)) ^ 0x7FF) : FLEXCAN_MB_ID_IDEXT(((id1) ^ (id1)) ^ 0x1FFFFFFF);
- setMBFilterProcessing(mb_num,id1,mask);
- filter_store(FLEXCAN_MULTI, mb_num, 1, id1, 0, 0, 0, 0);
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setMBFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2) {
- if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return 0; /* mailbox not available */
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return 0; /* exit on TX mailbox */
- uint32_t mask = ( !(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE) ) ? FLEXCAN_MB_ID_IDSTD(((id1 | id2) ^ (id1 & id2)) ^ 0x7FF) : FLEXCAN_MB_ID_IDEXT(((id1 | id2) ^ (id1 & id2)) ^ 0x1FFFFFFF);
- setMBFilterProcessing(mb_num,id1,mask);
- filter_store(FLEXCAN_MULTI, mb_num, 2, id1, id2, 0, 0, 0);
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setMBFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3) {
- if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return 0; /* mailbox not available */
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return 0; /* exit on TX mailbox */
- uint32_t mask = ( !(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE) ) ? FLEXCAN_MB_ID_IDSTD(((id1 | id2 | id3) ^ (id1 & id2 & id3)) ^ 0x7FF) : FLEXCAN_MB_ID_IDEXT(((id1 | id2 | id3) ^ (id1 & id2 & id3)) ^ 0x1FFFFFFF);
- setMBFilterProcessing(mb_num,id1,mask);
- filter_store(FLEXCAN_MULTI, mb_num, 3, id1, id2, id3, 0, 0);
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setMBFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4) {
- if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return 0; /* mailbox not available */
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return 0; /* exit on TX mailbox */
- uint32_t mask = ( !(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE) ) ? FLEXCAN_MB_ID_IDSTD(((id1 | id2 | id3 | id4) ^ (id1 & id2 & id3 & id4)) ^ 0x7FF) : FLEXCAN_MB_ID_IDEXT(((id1 | id2 | id3 | id4) ^ (id1 & id2 & id3 & id4)) ^ 0x1FFFFFFF);
- setMBFilterProcessing(mb_num,id1,mask);
- filter_store(FLEXCAN_MULTI, mb_num, 4, id1, id2, id3, id4, 0);
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setMBFilter(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5) {
- if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return 0; /* mailbox not available */
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return 0; /* exit on TX mailbox */
- uint32_t mask = ( !(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE) ) ? FLEXCAN_MB_ID_IDSTD(((id1 | id2 | id3 | id4 | id5) ^ (id1 & id2 & id3 & id4 & id5)) ^ 0x7FF) : FLEXCAN_MB_ID_IDEXT(((id1 | id2 | id3 | id4 | id5) ^ (id1 & id2 & id3 & id4 & id5)) ^ 0x1FFFFFFF);
- setMBFilterProcessing(mb_num,id1,mask);
- filter_store(FLEXCAN_MULTI, mb_num, 5, id1, id2, id3, id4, id5);
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setMBFilterRange(FLEXCAN_MAILBOX mb_num, uint32_t id1, uint32_t id2) {
- if ( mb_num < mailboxOffset() || mb_num >= FLEXCANb_MAXMB_SIZE(_bus) ) return 0; /* mailbox not available */
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, mb_num)) >> 3) ) return 0; /* exit on TX mailbox */
- if ( id1 > id2 || ((id2 > id1) && (id2-id1>1000)) || !id1 || !id2 ) return 0; /* don't play around... */
- uint32_t stage1 = id1, stage2 = id1;
- for ( uint32_t i = id1 + 1; i <= id2; i++ ) {
- stage1 |= i; stage2 &= i;
- }
- uint32_t mask = ( !(FLEXCANb_MBn_CS(_bus, mb_num) & FLEXCAN_MB_CS_IDE) ) ? FLEXCAN_MB_ID_IDSTD( (stage1 ^ stage2) ^ 0x1FFFFFFF ) : FLEXCAN_MB_ID_IDEXT( (stage1 ^ stage2) ^ 0x1FFFFFFF );
- setMBFilterProcessing(mb_num,id1,mask);
- filter_store(FLEXCAN_RANGE, mb_num, 2, id1, id2, 0, 0, 0);
- return 1;
- }
-
- FCTP_FUNC int FCTP_OPT::readFIFO(CAN_message_t &msg) {
- delayMicroseconds(150);
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN) ) return 0; /* FIFO is disabled */
- if ( !(FLEXCANb_MCR(_bus) & (1UL << 15)) ) { /* if DMA is not enabled, check interrupt flag, else continue. */
- if ( FLEXCANb_IMASK1(_bus) & FLEXCAN_IMASK1_BUF5M ) return 0; /* FIFO interrupt enabled, polling blocked */
- }
- if ( FLEXCANb_IFLAG1(_bus) & FLEXCAN_IFLAG1_BUF5I ) { /* message available */
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80));
- uint32_t code = mbxAddr[0];
- msg.len = (code & 0xF0000) >> 16;
- msg.flags.remote = (bool)(code & (1UL << 20));
- msg.flags.extended = (bool)(code & (1UL << 21));
- msg.timestamp = code & 0xFFFF;
- msg.id = (mbxAddr[1] & 0x1FFFFFFF) >> ((msg.flags.extended) ? 0 : 18);
- uint32_t data0 = mbxAddr[2];
- for ( int8_t d = 0; d < 4 ; d++ ) msg.buf[3 - d] = (uint8_t)(data0 >> (8 * d));
- uint32_t data1 = mbxAddr[3];
- for ( int8_t d = 0; d < 4 ; d++ ) msg.buf[7 - d] = (uint8_t)(data1 >> (8 * d));
- msg.bus = busNumber;
- msg.idhit = (uint8_t)(FLEXCANb_RXFIR(_bus) & 0x1FF);
- msg.mb = FIFO; /* store the mailbox the message came from (for callback reference) */
- if ( !(FLEXCANb_MCR(_bus) & (1UL << 15)) ) writeIFLAGBit(5); /* clear FIFO bit only, NOT FOR DMA USE! */
- frame_distribution(msg);
- if ( filter_match((FLEXCAN_MAILBOX)msg.mb, msg.id) ) return 1;
- }
- return 0; /* message not available */
- }
-
- FCTP_FUNC int FCTP_OPT::getFirstTxBox() {
- for (uint8_t i = mailboxOffset(); i < FLEXCANb_MAXMB_SIZE(_bus); i++) {
- if ( (FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, i)) >> 3) ) return i; // if TX
- }
- return -1;
- }
-
- FCTP_FUNC int FCTP_OPT::read(CAN_message_t &msg) {
- bool _random = random(0, 2);
- if ( ( !_random ) && ( FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN ) &&
- !( FLEXCANb_IMASK1(_bus) & FLEXCAN_IMASK1_BUF5M ) &&
- ( FLEXCANb_IFLAG1(_bus) & FLEXCAN_IFLAG1_BUF5I ) ) return readFIFO(msg);
- return readMB(msg);
- }
-
- FCTP_FUNC int FCTP_OPT::readMB(CAN_message_t &msg) {
- uint64_t iflag = 0;
- for ( uint8_t cycle_limit = 3, mailboxes = mailboxOffset(); mailbox_reader_increment <= FLEXCANb_MAXMB_SIZE(_bus); ++mailbox_reader_increment ) {
- iflag = readIFLAG();
- if ( iflag && (mailbox_reader_increment >= (64 - __builtin_clzll(iflag))) ) { /* break from MSB's if unset, add 1 to prevent undefined behaviour in clz for 0 check */
- mailbox_reader_increment = mailboxOffset();
- if ( !--cycle_limit ) return 0;
- }
- if ( FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN ) { /* FIFO is enabled, get only remaining RX (if any) */
- if ( mailbox_reader_increment < mailboxes ) mailbox_reader_increment = mailboxes - 1; /* go back to position end of fifo+filter region */
- }
- if ( mailbox_reader_increment >= FLEXCANb_MAXMB_SIZE(_bus) ) {
- mailbox_reader_increment = mailboxOffset();
- if ( !--cycle_limit ) return 0;
- }
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (mailbox_reader_increment * 0x10)));
- if ((readIMASK() & (1ULL << mailbox_reader_increment))) continue; /* don't read interrupt enabled mailboxes */
- uint32_t code = mbxAddr[0];
- if ( (FLEXCAN_get_code(code) >> 3) ) continue; /* skip TX mailboxes */
- //if (!(code & 0x600000) && !(iflag & (1ULL << mailbox_reader_increment))) continue; /* don't read unflagged mailboxes, errata: extended mailboxes iflags do not work in poll mode, must check CS field */
- if ( ( FLEXCAN_get_code(code) == FLEXCAN_MB_CODE_RX_FULL ) ||
- ( FLEXCAN_get_code(code) == FLEXCAN_MB_CODE_RX_OVERRUN ) ) {
- msg.flags.remote = (bool)(code & (1UL << 20));
- msg.flags.extended = (bool)(code & (1UL << 21));
- msg.id = (mbxAddr[1] & 0x1FFFFFFF) >> ((msg.flags.extended) ? 0 : 18);
- if ( FLEXCAN_get_code(code) == FLEXCAN_MB_CODE_RX_OVERRUN ) msg.flags.overrun = 1;
- msg.len = (code & 0xF0000) >> 16;
- msg.mb = mailbox_reader_increment++;
- msg.timestamp = code & 0xFFFF;
- msg.bus = busNumber;
- for ( uint8_t i = 0; i < (8 >> 2); i++ ) for ( int8_t d = 0; d < 4 ; d++ ) msg.buf[(4 * i) + 3 - d] = (uint8_t)(mbxAddr[2 + i] >> (8 * d));
- mbxAddr[0] = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY) | ((msg.flags.extended) ? (FLEXCAN_MB_CS_SRR | FLEXCAN_MB_CS_IDE) : 0);
- (void)FLEXCANb_TIMER(_bus);
- writeIFLAGBit(msg.mb);
- frame_distribution(msg);
- if ( filter_match((FLEXCAN_MAILBOX)msg.mb, msg.id) ) return 1;
- }
- }
- return 0; /* no messages available */
- }
-
- FCTP_FUNC void FCTP_OPT::struct2queueTx(const CAN_message_t &msg) {
- uint8_t buf[sizeof(CAN_message_t)];
- memmove(buf, &msg, sizeof(msg));
- txBuffer.push_back(buf, sizeof(CAN_message_t));
- }
-
- FCTP_FUNC int FCTP_OPT::write(FLEXCAN_MAILBOX mb_num, const CAN_message_t &msg) {
- if ( mb_num < mailboxOffset() ) return 0; /* FIFO doesn't transmit */
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (mb_num * 0x10)));
- if ( !((FLEXCAN_get_code(mbxAddr[0])) >> 3) ) return 0; /* not a transmit mailbox */
- if ( msg.seq && FLEXCAN_get_code(mbxAddr[0]) != FLEXCAN_MB_CODE_TX_INACTIVE ) return 0; /* non blocking resend sequential frames */
- uint32_t timeout = millis();
- while ( FLEXCAN_get_code(mbxAddr[0]) != FLEXCAN_MB_CODE_TX_INACTIVE ) {
- if ( millis() - timeout > 100 ) return 0;
- }
- writeTxMailbox(mb_num, msg);
- return 1; // transmit entry accepted //
- }
-
- FCTP_FUNC int FCTP_OPT::write(const CAN_message_t &msg) {
- if ( msg.seq ) {
- if ( !write((FLEXCAN_MAILBOX)getFirstTxBox(), msg) ) struct2queueTx(msg);
- return 1;
- }
- for (uint8_t i = mailboxOffset(); i < FLEXCANb_MAXMB_SIZE(_bus); i++) {
- if ( FLEXCAN_get_code(FLEXCANb_MBn_CS(_bus, i)) == FLEXCAN_MB_CODE_TX_INACTIVE ) {
- writeTxMailbox(i, msg);
- return 1; /* transmit entry accepted */
- }
- }
- return 0; /* transmit entry failed, no mailboxes or queues available */
- }
-
- FCTP_FUNC void FCTP_OPT::onReceive(const FLEXCAN_MAILBOX &mb_num, _MB_ptr handler) {
- if ( FIFO == mb_num ) {
- _mbHandlers[0] = handler;
- return;
- }
- _mbHandlers[mb_num] = handler;
- }
-
- FCTP_FUNC void FCTP_OPT::onReceive(_MB_ptr handler) {
- _mainHandler = handler;
- }
-
- FCTP_FUNC uint64_t FCTP_OPT::events() {
- if ( rxBuffer.size() ) {
- CAN_message_t frame;
- uint8_t buf[sizeof(CAN_message_t)];
- rxBuffer.pop_front(buf, sizeof(CAN_message_t));
- memmove(&frame, buf, sizeof(frame));
- mbCallbacks((FLEXCAN_MAILBOX)frame.mb, frame);
- }
- if ( txBuffer.size() ) {
- CAN_message_t frame;
- uint8_t buf[sizeof(CAN_message_t)];
- txBuffer.peek_front(buf, sizeof(CAN_message_t));
- memmove(&frame, buf, sizeof(frame));
- if ( write((FLEXCAN_MAILBOX)getFirstTxBox(), frame) ) txBuffer.pop_front();
- }
- return (uint64_t)(rxBuffer.size() << 12) | txBuffer.size();
- }
-
- #if defined(__IMXRT1062__)
- static void flexcan_isr_can1() {
- if ( _CAN1 ) _CAN1->flexcan_interrupt();
- }
-
- static void flexcan_isr_can2() {
- if ( _CAN2 ) _CAN2->flexcan_interrupt();
- }
-
- static void flexcan_isr_can3() {
- if ( _CAN3 ) _CAN3->flexcan_interrupt();
- }
- #endif
- #if defined(__MK20DX256__) || defined(__MK64FX512__)
- static void flexcan_isr_can0() {
- if ( _CAN0 ) _CAN0->flexcan_interrupt();
- }
- #endif
- #if defined(__MK66FX1M0__)
- static void flexcan_isr_can0() {
- if ( _CAN0 ) _CAN0->flexcan_interrupt();
- }
- static void flexcan_isr_can1() {
- if ( _CAN1 ) _CAN1->flexcan_interrupt();
- }
- #endif
-
-
- FCTP_FUNC void FCTP_OPT::mbCallbacks(const FLEXCAN_MAILBOX &mb_num, const CAN_message_t &msg) {
- if ( mb_num == FIFO ) {
- if ( _mbHandlers[0] ) _mbHandlers[0](msg);
- if ( _mainHandler ) _mainHandler(msg);
- return;
- }
- if ( _mbHandlers[mb_num] ) _mbHandlers[mb_num](msg);
- if ( _mainHandler ) _mainHandler(msg);
- }
-
- FCTP_FUNC void FCTP_OPT::struct2queueRx(const CAN_message_t &msg) {
- uint8_t buf[sizeof(CAN_message_t)];
- memmove(buf, &msg, sizeof(msg));
- rxBuffer.push_back(buf, sizeof(CAN_message_t));
- }
-
- FCTP_FUNC void FCTP_OPT::flexcan_interrupt() {
- CAN_message_t msg; // setup a temporary storage buffer
- uint64_t imask = readIMASK(), iflag = readIFLAG();
-
- if ( !(FLEXCANb_MCR(_bus) & (1UL << 15)) ) { /* if DMA is disabled, ONLY THEN you can handle FIFO in ISR */
- if ( (FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN) && (imask & FLEXCAN_IMASK1_BUF5M) && (iflag & FLEXCAN_IFLAG1_BUF5I) ) { /* FIFO is enabled, capture frames if triggered */
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (0 * 0x10)));
- uint32_t code = mbxAddr[0];
- msg.len = (code & 0xF0000) >> 16;
- msg.flags.remote = (bool)(code & (1UL << 20));
- msg.flags.extended = (bool)(code & (1UL << 21));
- msg.timestamp = code & 0xFFFF;
- msg.id = (mbxAddr[1] & 0x1FFFFFFF) >> ((msg.flags.extended) ? 0 : 18);
- msg.idhit = code >> 23;
- for ( uint8_t i = 0; i < (8 >> 2); i++ ) for ( int8_t d = 0; d < 4 ; d++ ) msg.buf[(4 * i) + 3 - d] = (uint8_t)(mbxAddr[2 + i] >> (8 * d));
- msg.bus = busNumber;
- msg.mb = FIFO; /* store the mailbox the message came from (for callback reference) */
- (void)FLEXCANb_TIMER(_bus);
- writeIFLAGBit(5); /* clear FIFO bit only! */
- if ( iflag & FLEXCAN_IFLAG1_BUF6I ) writeIFLAGBit(6); /* clear FIFO bit only! */
- if ( iflag & FLEXCAN_IFLAG1_BUF7I ) writeIFLAGBit(7); /* clear FIFO bit only! */
- frame_distribution(msg);
- ext_output1(msg);
- ext_output2(msg);
- ext_output3(msg);
- if (fifo_filter_match(msg.id)) struct2queueRx(msg);
- }
- }
-
- uint8_t exit_point = 64 - __builtin_clzll(iflag | 1); /* break from MSB's if unset, add 1 to prevent undefined behaviour in clz for 0 check */
- for ( uint8_t mb_num = mailboxOffset(); mb_num < FLEXCANb_MAXMB_SIZE(_bus); mb_num++ ) {
- if ( mb_num >= exit_point ) break; /* early exit from higher unflagged mailboxes */
- if (!(imask & (1ULL << mb_num))) continue; /* don't read non-interrupt mailboxes */
- if (!(iflag & (1ULL << mb_num))) continue; /* don't read unflagged mailboxes */
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (mb_num * 0x10)));
- uint32_t code = mbxAddr[0];
- if ( ( FLEXCAN_get_code(code) == FLEXCAN_MB_CODE_RX_FULL ) ||
- ( FLEXCAN_get_code(code) == FLEXCAN_MB_CODE_RX_OVERRUN ) ) {
- msg.flags.extended = (bool)(code & (1UL << 21));
- msg.id = (mbxAddr[1] & 0x1FFFFFFF) >> ((msg.flags.extended) ? 0 : 18);
- if ( FLEXCAN_get_code(code) == FLEXCAN_MB_CODE_RX_OVERRUN ) msg.flags.overrun = 1;
- msg.len = (code & 0xF0000) >> 16;
- msg.mb = mb_num;
- msg.timestamp = code & 0xFFFF;
- msg.bus = busNumber;
- for ( uint8_t i = 0; i < (8 >> 2); i++ ) for ( int8_t d = 0; d < 4 ; d++ ) msg.buf[(4 * i) + 3 - d] = (uint8_t)(mbxAddr[2 + i] >> (8 * d));
- mbxAddr[0] = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY) | ((msg.flags.extended) ? (FLEXCAN_MB_CS_SRR | FLEXCAN_MB_CS_IDE) : 0);
- (void)FLEXCANb_TIMER(_bus);
- writeIFLAGBit(mb_num);
- if ( filter_match((FLEXCAN_MAILBOX)mb_num, msg.id) ) struct2queueRx(msg); /* store frame in queue */
- frame_distribution(msg);
- ext_output1(msg);
- ext_output2(msg);
- ext_output3(msg);
- }
- if ( FLEXCAN_get_code(code) == FLEXCAN_MB_CODE_TX_INACTIVE ) {
- writeIFLAGBit(mb_num); /* clear IFLAG, currently unused */
- }
- }
- FLEXCANb_ESR1(_bus) |= FLEXCANb_ESR1(_bus);
- }
-
- FCTP_FUNC void FCTP_OPT::enableDMA(bool state) { /* only CAN3 supports this on 1062, untested */
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- ( !state ) ? FLEXCANb_MCR(_bus) &= ~0x8000 : FLEXCANb_MCR(_bus) |= 0x8000;
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC uint8_t FCTP_OPT::setRFFN(FLEXCAN_RFFN_TABLE rffn) {
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- FLEXCAN_set_rffn(FLEXCANb_CTRL2(_bus), rffn);
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- uint32_t remaining_mailboxes = FLEXCANb_MAXMB_SIZE(_bus) - 6 /* MAXMB - FIFO */ - ((((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 2);
- if ( FLEXCANb_MAXMB_SIZE(_bus) < (6 + ((((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 2))) remaining_mailboxes = 0;
- return constrain((uint8_t)(FLEXCANb_MAXMB_SIZE(_bus) - remaining_mailboxes), 0, 32);
- }
-
- FCTP_FUNC void FCTP_OPT::setFIFOFilter(const FLEXCAN_FLTEN &input) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN )) return; /* FIFO not enabled. */
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- for (uint8_t i = 0; i < max_fifo_filters; i++) { /* block all ID's so filtering could be applied. */
- if ( input == REJECT_ALL ) {
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 0 ) { /* If Table A is chosen for FIFO */
- FLEXCANb_IDFLT_TAB(_bus, i) = 0xFFFFFFFF; /* reset id */
- /* individual masks (RXIMR) will just cover Rx FIFO filters in 0-31 range, and filters 32-127
- will use RXFGMASK. */
- if ( i < constrain(mailboxOffset(), 0, 32) ) FLEXCANb_RXIMR(_bus, i) = 0x3FFFFFFF; // (RXIMR) /* block all id's (0-31) */
- FLEXCANb_RXFGMASK(_bus) = 0x3FFFFFFF;
- }
- else if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 1 ) { /* If Table B is chosen for FIFO */
- FLEXCANb_IDFLT_TAB(_bus, i) = 0xFFFFFFFF; /* reset id */
- if ( i < constrain(mailboxOffset(), 0, 32) ) FLEXCANb_RXIMR(_bus, i) = 0x7FFF7FFF; // (RXIMR) /* block all id's (0-31) */
- FLEXCANb_RXFGMASK(_bus) = 0x7FFF7FFF;
- }
- else if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 2 ) { /* If Table C is chosen for FIFO */
- /* TO BE DONE */ //FLEXCANb_IDFLT_TAB(_bus, i) = 0x6E6E6E6E; /* reset id */
- //FLEXCANb_RXIMR(_bus, i) = 0xFFFFFFFF; // (RXIMR) /* block all id's */
- }
- }
- else if ( input == ACCEPT_ALL ) {
- FLEXCANb_IDFLT_TAB(_bus, i) = 0; /* reset id */
- if ( i < constrain(mailboxOffset(), 0, 32) ) FLEXCANb_RXIMR(_bus, i) = 0; // (RXIMR) /* allow all id's */
- FLEXCANb_RXFGMASK(_bus) = 0; /* for masks above IDF 0->31, global is used for rest) */
- }
- }
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC bool FCTP_OPT::setFIFOFilter(uint8_t filter, uint32_t id1, const FLEXCAN_IDE &ide, const FLEXCAN_IDE &remote) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN )) return 0; /* FIFO not enabled. */
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- if ( filter >= max_fifo_filters ) return 0;
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- /* ##################################### TABLE A ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 0 ) {
- uint32_t mask = ( ide != EXT ) ? ((((id1) ^ (id1)) ^ 0x7FF) << 19 ) | 0xC0000001 : ((((id1) ^ (id1)) ^ 0x1FFFFFFF) << 1 ) | 0xC0000001;
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide == EXT ? 1 : 0) << 30) | ((remote == RTR ? 1 : 0) << 31) |
- ((ide == EXT ? ((id1 & FLEXCAN_MB_ID_EXT_MASK) << 1) : (FLEXCAN_MB_ID_IDSTD(id1) << 1)));
- if ( filter < constrain(mailboxOffset(), 0, 32) ) FLEXCANb_RXIMR(_bus, filter) = mask;// | ((filter < (max_fifo_filters / 2)) ? 0 : (1UL << 30)); // (RXIMR)
- FLEXCANb_RXFGMASK(_bus) = 0x3FFFFFFF; /* enforce it for blocks 32->127, single IDs */
-
- fifo_filter_table[filter][0] = ( ((ide == EXT) ? 1UL : 0UL) << 16); /* extended flag check */
- fifo_filter_store(FLEXCAN_MULTI, filter, 1, id1, 0, 0, 0, 0);
- }
- /* #################################################################################### */
- /* ##################################### TABLE B ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 1 ) {
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide == EXT ? 1 : 0) << 30) | ((ide == EXT ? 1 : 0) << 14) | /* STD IDs / EXT IDs */
- ((remote == RTR ? 1 : 0) << 31) | ((remote == RTR ? 1 : 0) << 15) | /* remote frames */
- (ide == EXT ? ((id1 >> (29 - 14)) << 16) : ((id1 & 0x7FF) << 19)) | /* first ID is EXT or STD? */
- (ide == EXT ? ((id1 >> (29 - 14)) << 0) : ((id1 & 0x7FF) << 3)) ; /* second ID is EXT or STD? */
- uint32_t mask = ( ide != EXT ) ? ((((id1) ^ (id1)) ^ 0x7FF) << 19 ) | ((remote == RTR)?(1UL<<31):0UL) : ((((id1) ^ (id1)) ^ 0x1FFFFFFF) << 16 ) | ((remote == RTR)?(1UL<<31):0UL);
- mask |= (( ide != EXT ) ? ((((id1) ^ (id1)) ^ 0x7FF) << 3 ) | ((remote == RTR)?(1UL<<15):0UL) : ((((id1) ^ (id1)) ^ 0x1FFFFFFF) << 0 ) | ((remote == RTR)?(1UL<<15):0UL) ) & 0xFFFF;
- mask |= (1UL<<30) | (1UL<<14);
- if ( filter < constrain(mailboxOffset(), 0, 32) ) FLEXCANb_RXIMR(_bus, filter) = mask; // (RXIMR)
- FLEXCANb_RXFGMASK(_bus) = 0x7FFF7FFF; /* enforce it for blocks 32->127, single STD IDs / EXT partial matches */
- }
-
- /* #################################################################################### */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- return 1;
- }
-
- FCTP_FUNC void FCTP_OPT::fifo_filter_store(FLEXCAN_FILTER_TABLE type, uint8_t filter, uint32_t id_count, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5) {
- fifo_filter_table[filter][0] = (fifo_filter_table[filter][0] & 0xF0000) | filter; // first 7 bits reserved for fifo filter
- fifo_filter_table[filter][0] |= (id_count << 7); // we store the quantity of ids after the fifo filter count
- /* bit 16-19: extended ids */
- /* bit 28: filter enabled */
- fifo_filter_table[filter][0] |= (type << 29); // we reserve 3 upper bits for type
- fifo_filter_table[filter][1] = id1; // id1
- fifo_filter_table[filter][2] = id2; // id2
- fifo_filter_table[filter][3] = id3; // id3
- fifo_filter_table[filter][4] = id4; // id4
- fifo_filter_table[filter][5] = id5; // id5
- }
-
- FCTP_FUNC void FCTP_OPT::enhanceFilter(FLEXCAN_MAILBOX mb_num) {
- if ( mb_num == FIFO && !(fifo_filter_table[0][0] & 0xE0000000) ) return;
- else if ( !(mb_filter_table[mb_num][0] & 0xE0000000) ) return;
- if ( mb_num == FIFO ) fifo_filter_table[0][0] |= (1UL << 28); /* enable fifo enhancement */
- else mb_filter_table[mb_num][0] |= (1UL << 28); /* enable mb enhancement */
- }
-
- FCTP_FUNC volatile bool FCTP_OPT::fifo_filter_match(uint32_t id) {
- if ( !(fifo_filter_table[0][0] & 0x10000000) ) return 1;
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- for (uint8_t mb_num = 0; mb_num < max_fifo_filters; mb_num++) { /* check fifo filters */
- if ( (fifo_filter_table[mb_num][0] >> 29) == FLEXCAN_MULTI ) {
- for ( uint8_t i = 0; i < ((fifo_filter_table[mb_num][0] & 0x380) >> 7); i++) if ( id == fifo_filter_table[mb_num][i+1] ) return 1;
- }
- else if ( (fifo_filter_table[mb_num][0] >> 29) == FLEXCAN_RANGE ) {
- if ( id >= fifo_filter_table[mb_num][1] && id <= fifo_filter_table[mb_num][2] ) return 1;
- }
- }
- return 0;
- }
-
- FCTP_FUNC volatile bool FCTP_OPT::filter_match(FLEXCAN_MAILBOX mb_num, uint32_t id) {
- if ( !(mb_filter_table[mb_num][0] & 0x10000000) ) return 1;
- if ( (mb_filter_table[mb_num][0] >> 29) == FLEXCAN_MULTI ) {
- for ( uint8_t i = 0; i < ((mb_filter_table[mb_num][0] & 0x380) >> 7); i++) if ( id == mb_filter_table[mb_num][i+1] ) return 1;
- }
- else if ( (mb_filter_table[mb_num][0] >> 29) == FLEXCAN_RANGE ) {
- if ( id >= mb_filter_table[mb_num][1] && id <= mb_filter_table[mb_num][2] ) return 1;
- }
- return 0;
- }
-
- FCTP_FUNC bool FCTP_OPT::setFIFOFilter(uint8_t filter, uint32_t id1, uint32_t id2, const FLEXCAN_IDE &ide, const FLEXCAN_IDE &remote) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN )) return 0; /* FIFO not enabled. */
- if ( filter > 31 ) return 0; /* multi-id & ranges are not allowed */
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- if ( filter >= max_fifo_filters ) return 0;
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- /* ##################################### TABLE A ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 0 ) {
- uint32_t mask = ( ide != EXT ) ? ((((id1 | id2) ^ (id1 & id2)) ^ 0x7FF) << 19 ) | 0xC0000001 : ((((id1 | id2) ^ (id1 & id2)) ^ 0x1FFFFFFF) << 1 ) | 0xC0000001;
- FLEXCANb_RXIMR(_bus, filter) = mask; // (RXIMR)
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide == EXT ? 1 : 0) << 30) | ((remote == RTR ? 1 : 0) << 31) |
- ((ide == EXT ? ((id1 & FLEXCAN_MB_ID_EXT_MASK) << 1) : (FLEXCAN_MB_ID_IDSTD(id1) << 1)));
-
- fifo_filter_table[filter][0] = ( ((ide == EXT) ? 1UL : 0UL) << 16); /* extended flag check */
- fifo_filter_store(FLEXCAN_MULTI, filter, 2, id1, id2, 0, 0, 0);
- }
- /* #################################################################################### */
- /* ##################################### TABLE B ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 1 ) {
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide == EXT ? 1 : 0) << 30) | ((ide == EXT ? 1 : 0) << 14) | /* STD IDs / EXT IDs */
- ((remote == RTR ? 1 : 0) << 31) | ((remote == RTR ? 1 : 0) << 15) | /* remote frames */
- (ide == EXT ? ((id1 >> (29 - 14)) << 16) : ((id1 & 0x7FF) << 19)) | /* first ID is EXT or STD? */
- (ide == EXT ? ((id2 >> (29 - 14)) << 0) : ((id2 & 0x7FF) << 3)) ; /* second ID is EXT or STD? */
- uint32_t mask = ( ide != EXT ) ? ((((id1) ^ (id1)) ^ 0x7FF) << 19 ) | ((remote == RTR)?(1UL<<31):0UL) : ((((id1) ^ (id1)) ^ 0x1FFFFFFF) << 16 ) | ((remote == RTR)?(1UL<<31):0UL);
- mask |= (( ide != EXT ) ? ((((id2) ^ (id2)) ^ 0x7FF) << 3 ) | ((remote == RTR)?(1UL<<15):0UL) : ((((id2) ^ (id2)) ^ 0x1FFFFFFF) << 0 ) | ((remote == RTR)?(1UL<<15):0UL) ) & 0xFFFF;
- mask |= (1UL<<30) | (1UL<<14);
- FLEXCANb_RXIMR(_bus, filter) = mask; // (RXIMR)
- }
- /* #################################################################################### */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setFIFOFilterRange(uint8_t filter, uint32_t id1, uint32_t id2, const FLEXCAN_IDE &ide, const FLEXCAN_IDE &remote) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN )) return 0; /* FIFO not enabled. */
- if ( filter > 31 ) return 0; /* multi-id & ranges are not allowed */
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- if ( filter >= max_fifo_filters ) return 0;
- if ( id1 > id2 || ((id2 > id1) && (id2 - id1 > 1000)) || !id1 || !id2 ) return 0; /* don't play around... */
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- /* ##################################### TABLE A ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 0 ) {
- uint32_t stage1 = id1, stage2 = id1;
- for ( uint32_t i = id1 + 1; i <= id2; i++ ) {
- stage1 |= i; stage2 &= i;
- }
- uint32_t mask = ( ide != EXT ) ? (((stage1 ^ stage2) ^ 0x7FF) << 19) | 0xC0000001 : (((stage1 ^ stage2) ^ 0x1FFFFFFF) << 1) | 0xC0000001;
- FLEXCANb_RXIMR(_bus, filter) = mask; // (RXIMR)
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide == EXT ? 1 : 0) << 30) | ((remote == RTR ? 1 : 0) << 31) |
- ((ide == EXT ? ((id1 & FLEXCAN_MB_ID_EXT_MASK) << 1) : (FLEXCAN_MB_ID_IDSTD(id1) << 1)));
-
- fifo_filter_table[filter][0] = ( ((ide == EXT) ? 1UL : 0UL) << 16); /* extended flag check */
- fifo_filter_store(FLEXCAN_RANGE, filter, 2, id1, id2, 0, 0, 0);
- }
- /* #################################################################################### */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setFIFOFilter(uint8_t filter, uint32_t id1, const FLEXCAN_IDE &ide1, const FLEXCAN_IDE &remote1, uint32_t id2, const FLEXCAN_IDE &ide2, const FLEXCAN_IDE &remote2) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN )) return 0; /* FIFO not enabled. */
- if ( filter > 31 ) return 0; /* multi-id & ranges are not allowed */
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- if ( filter >= max_fifo_filters ) return 0;
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- /* ##################################### TABLE B ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 1 ) {
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide1 == EXT ? 1 : 0) << 30) | ((ide2 == EXT ? 1 : 0) << 14) | /* STD IDs / EXT IDs */
- ((remote1 == RTR ? 1 : 0) << 31) | ((remote2 == RTR ? 1 : 0) << 15) | /* remote frames */
- (ide1 == EXT ? ((id1 >> (29 - 14)) << 16) : ((id1 & 0x7FF) << 19)) | /* first ID is EXT or STD? */
- (ide2 == EXT ? ((id2 >> (29 - 14)) << 0) : ((id2 & 0x7FF) << 3)) ; /* second ID is EXT or STD? */
- uint32_t mask = ( ide1 != EXT ) ? ((((id1) ^ (id1)) ^ 0x7FF) << 19 ) | ((remote1 == RTR)?(1UL<<31):0UL) : ((((id1) ^ (id1)) ^ 0x1FFFFFFF) << 16 ) | ((remote1 == RTR)?(1UL<<31):0UL);
- mask |= (( ide2 != EXT ) ? ((((id2) ^ (id2)) ^ 0x7FF) << 3 ) | ((remote2 == RTR)?(1UL<<15):0UL) : ((((id2) ^ (id2)) ^ 0x1FFFFFFF) << 0 ) | ((remote2 == RTR)?(1UL<<15):0UL) ) & 0xFFFF;
- mask |= (1UL<<30) | (1UL<<14);
- FLEXCANb_RXIMR(_bus, filter) = mask; // (RXIMR)
- }
- /* #################################################################################### */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setFIFOFilter(uint8_t filter, uint32_t id1, uint32_t id2, const FLEXCAN_IDE &ide1, const FLEXCAN_IDE &remote1, uint32_t id3, uint32_t id4, const FLEXCAN_IDE &ide2, const FLEXCAN_IDE &remote2) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN )) return 0; /* FIFO not enabled. */
- if ( filter > 31 ) return 0; /* multi-id & ranges are not allowed */
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- if ( filter >= max_fifo_filters ) return 0;
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- /* ##################################### TABLE B ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 1 ) {
- uint32_t mask = ( ide1 != EXT ) ? ((((id1 | id2) ^ (id1 & id2)) ^ 0x7FF) << 19 ) | ((remote1 == RTR)?(1UL<<31):0UL) : ((((id1 | id2) ^ (id1 & id2)) ^ 0x1FFFFFFF) << 16 ) | ((remote1 == RTR)?(1UL<<31):0UL);
- mask |= (( ide2 != EXT ) ? ((((id3 | id4) ^ (id3 & id4)) ^ 0x7FF) << 3 ) | ((remote2 == RTR)?(1UL<<15):0UL) : ((((id3 | id4) ^ (id3 & id4)) ^ 0x1FFFFFFF) << 0 ) | ((remote2 == RTR)?(1UL<<15):0UL) ) & 0xFFFF;
- mask |= (1UL<<30) | (1UL<<14);
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide1 == EXT ? 1 : 0) << 30) | ((ide2 == EXT ? 1 : 0) << 14) | /* STD IDs / EXT IDs */
- ((remote1 == RTR ? 1 : 0) << 31) | ((remote2 == RTR ? 1 : 0) << 15) | /* remote frames */
- (ide1 == EXT ? ((id1 >> (29 - 14)) << 16) : ((id1 & 0x7FF) << 19)) | /* first ID is EXT or STD? */
- (ide2 == EXT ? ((id3 >> (29 - 14)) << 0 ) : ((id3 & 0x7FF) << 3 )) ; /* second ID is EXT or STD? */
- FLEXCANb_RXIMR(_bus, filter) = mask; // (RXIMR)
- }
- /* #################################################################################### */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- return 1;
- }
-
- FCTP_FUNC bool FCTP_OPT::setFIFOFilterRange(uint8_t filter, uint32_t id1, uint32_t id2, const FLEXCAN_IDE &ide1, const FLEXCAN_IDE &remote1, uint32_t id3, uint32_t id4, const FLEXCAN_IDE &ide2, const FLEXCAN_IDE &remote2) {
- if ( !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN )) return 0; /* FIFO not enabled. */
- if ( filter > 31 ) return 0; /* multi-id & ranges are not allowed */
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- if ( filter >= max_fifo_filters ) return 0;
- if ( id1 > id2 || ((id2 > id1) && (id2 - id1 > 1000)) || !id1 || !id2 ) return 0; /* don't play around... */
- if ( id3 > id4 || ((id4 > id3) && (id4 - id3 > 1000)) || !id3 || !id4 ) return 0; /* don't play around... */
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- /* ##################################### TABLE B ###################################### */
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 1 ) {
- uint32_t stage1 = id1, stage2 = id1;
- for ( uint32_t i = id1 + 1; i <= id2; i++ ) {
- stage1 |= i; stage2 &= i;
- }
- uint32_t mask = ( ide1 != EXT ) ? ((((stage1 | stage2) ^ (stage1 & stage2)) ^ 0x7FF) << 19 ) | ((remote1 == RTR)?(1UL<<31):0UL) : ((((stage1 | stage2) ^ (stage1 & stage2)) ^ 0x1FFFFFFF) << 16 ) | ((remote1 == RTR)?(1UL<<31):0UL);
- stage1 = stage2 = id3;
- for ( uint32_t i = id3 + 1; i <= id4; i++ ) {
- stage1 |= i; stage2 &= i;
- }
- mask |= (( ide2 != EXT ) ? ((((stage1 | stage2) ^ (stage1 & stage2)) ^ 0x7FF) << 3 ) | ((remote2 == RTR)?(1UL<<15):0UL) : ((((stage1 | stage2) ^ (stage1 & stage2)) ^ 0x1FFFFFFF) << 0 ) | ((remote2 == RTR)?(1UL<<15):0UL) ) & 0xFFFF;
- mask |= (1UL<<30) | (1UL<<14);
- FLEXCANb_IDFLT_TAB(_bus, filter) = ((ide1 == EXT ? 1 : 0) << 30) | ((ide2 == EXT ? 1 : 0) << 14) | /* STD IDs / EXT IDs */
- ((remote1 == RTR ? 1 : 0) << 31) | ((remote2 == RTR ? 1 : 0) << 15) | /* remote frames */
- (ide1 == EXT ? ((id1 >> (29 - 14)) << 16) : ((id1 & 0x7FF) << 19)) | /* first ID is EXT or STD? */
- (ide2 == EXT ? ((id3 >> (29 - 14)) << 0 ) : ((id3 & 0x7FF) << 3 )) ; /* second ID is EXT or STD? */
- FLEXCANb_RXIMR(_bus, filter) = mask; // (RXIMR)
- }
- /* #################################################################################### */
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- return 1;
- }
-
- FCTP_FUNC void FCTP_OPT::setFIFOFilterTable(FLEXCAN_FIFOTABLE letter) {
- bool frz_flag_negate = !(FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FRZ_ACK);
- FLEXCAN_EnterFreezeMode();
- FLEXCANb_MCR(_bus) = (FLEXCANb_MCR(_bus) & 0xFFFFFCFF) | FLEXCAN_MCR_IDAM(letter);
- if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 0 ) FLEXCANb_RXFGMASK(_bus) = 0x3FFFFFFF;
- else if ( ((FLEXCANb_MCR(_bus) & FLEXCAN_MCR_IDAM_MASK) >> FLEXCAN_MCR_IDAM_BIT_NO) == 1 ) FLEXCANb_RXFGMASK(_bus) = 0x7FFF7FFF;
- if ( frz_flag_negate ) FLEXCAN_ExitFreezeMode();
- }
-
- FCTP_FUNC void FCTP_OPT::filter_store(FLEXCAN_FILTER_TABLE type, FLEXCAN_MAILBOX mb_num, uint32_t id_count, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5) {
- mb_filter_table[mb_num][0] = mb_num; // first 7 bits reserved for MB
- mb_filter_table[mb_num][0] |= (id_count << 7); // we store the quantity of ids after the mailboxes
- /* bit 28: filter enabled */
- mb_filter_table[mb_num][0] |= (type << 29); // we reserve 3 upper bits for type
- volatile uint32_t *mbxAddr = &(*(volatile uint32_t*)(_bus + 0x80 + (mb_num * 0x10)));
- mb_filter_table[mb_num][0] |= ( ((mbxAddr[0] & 0x600000) ? 1UL : 0UL) << 27); /* extended flag check */
- mb_filter_table[mb_num][1] = id1; // id1
- mb_filter_table[mb_num][2] = id2; // id2
- mb_filter_table[mb_num][3] = id3; // id3
- mb_filter_table[mb_num][4] = id4; // id4
- mb_filter_table[mb_num][5] = id5; // id5
- }
-
- FCTP_FUNC volatile void FCTP_OPT::frame_distribution(CAN_message_t &msg) {
- if ( !distribution ) return; /* distribution not enabled */
- CAN_message_t frame = msg;
-
- if ( FLEXCANb_MCR(_bus) & FLEXCAN_MCR_FEN ) {
- uint8_t max_fifo_filters = (((FLEXCANb_CTRL2(_bus) >> FLEXCAN_CTRL2_RFFN_BIT_NO) & 0xF) + 1) * 8; // 8->128
- for (uint8_t i = 0; i < max_fifo_filters; i++) { /* check fifo filters */
- if ( msg.mb == FIFO ) break; // don't distribute to fifo if fifo was the source
- if ( !(fifo_filter_table[i][0] & 0xE0000000) ) continue; // skip unset filters
-
- if ( (fifo_filter_table[i][0] >> 29) == FLEXCAN_MULTI ) {
- if ( (bool)(fifo_filter_table[i][0] & (1UL << 16)) != msg.flags.extended ) continue; /* extended flag check */
- for ( uint8_t p = 0; p < ((fifo_filter_table[i][0] & 0x380) >> 7); p++) {
- if ( frame.id == fifo_filter_table[i][p+1] ) {
- frame.mb = FIFO;
- struct2queueRx(frame);
- }
- }
- }
- else if ( (fifo_filter_table[i][0] >> 29) == FLEXCAN_RANGE ) {
- if ( (bool)(fifo_filter_table[i][0] & (1UL << 16)) != msg.flags.extended ) continue; /* extended flag check */
- if ( frame.id >= fifo_filter_table[i][1] && frame.id <= fifo_filter_table[i][2] ) {
- frame.mb = FIFO;
- struct2queueRx(frame);
- }
- }
- } /* end of fifo scan */
- } /* end of fifo checking */
-
- for ( uint8_t i = mailboxOffset(); i < FLEXCANb_MAXMB_SIZE(_bus); i++ ) {
- if ( msg.mb == i ) continue; // don't distribute to same mailbox
- if ( !(mb_filter_table[i][0] & 0xE0000000) ) continue; // skip unset filters
- if ( (bool)(mb_filter_table[i][0] & (1UL << 27)) != msg.flags.extended ) continue; /* extended flag check */
- if ( (mb_filter_table[i][0] >> 29) == FLEXCAN_MULTI ) {
- for ( uint8_t p = 0; p < ((mb_filter_table[i][0] & 0x380) >> 7); p++) {
- if ( frame.id == mb_filter_table[i][p+1] ) {
- frame.mb = i;
- struct2queueRx(frame);
- }
- }
- }
- else if ( (mb_filter_table[i][0] >> 29) == FLEXCAN_RANGE ) {
- if ( frame.id >= mb_filter_table[i][1] && frame.id <= mb_filter_table[i][2] ) {
- frame.mb = i;
- struct2queueRx(frame);
- }
- }
- } /* end of mb scan */
-
- }
-
- extern void __attribute__((weak)) ext_output1(const CAN_message_t &msg);
- extern void __attribute__((weak)) ext_output2(const CAN_message_t &msg);
- extern void __attribute__((weak)) ext_output3(const CAN_message_t &msg);
|