当前位置:   article > 正文

S32K CAN FIFO driver(no SDK)

s32k can fifo

S32K14X_CAN2.0_RxFIFO_driver

S32K14X CAN2.0收发数据帧配置(no SDK)

1、工作原理
在这里插入图片描述
在这里插入图片描述
When MCR[RFEN] is set, the memory area from 0x80 to 0xDC (which is normally
occupied by MBs 0–5) is used by the reception FIFO engine.
The region 0x80-0x8C contains the output of the FIFO which must be read by the CPU as
a message buffer. This output contains the oldest message that has been received but not
yet read. The region 0x90-0xDC is reserved for internal use of the FIFO engine.

我们从Rx FIFO架构看出,CAN2.0帧使用滤波模式接收,1MB(message buffer)占用4word,每个word对应4byte。其中前面2个word表示长度、时间戳、IDE、RTR、CAN ID等信息,后2个word表示CAN数据段8byte。所以在RAM Message Buffers分配时,MB0作为存放帧头和数据域,MB1~MB5 被保留给FIFO引擎的内部使用。MB6-MB7默认是CAN ID过滤表元素0-1,MB8-MB37是可配置ID过滤表元素2-127,至于ID 过滤表元素组的分配由CTRL2[RFFN]值决定,具体见下表。
在这里插入图片描述
这里再谈谈ID table elements formats,总共三种elements formats,具体格式由MCR[IDAM]值决定(下面例程选用Format A),见下图。
在这里插入图片描述
在这里插入图片描述

2、代码编写
FlexCAN initialization sequence
在这里插入图片描述
在这里插入图片描述

/*
 * ===================================================
 * Function :  FLEXCAN0_init For Classical CAN2.0 
 * 1. CAN configuration, set baud rate = 500Kbps 
 * 2. @note CAN Baud rate calculation
 *    Tq = (PRESDIV + 1) / f_canclk = 1 / 8M 
 *    1 CAN Bit Time = (1 + (PROPSEG + PSEG1 + 2) + (PSEG2 + 1)) * Tq
 *    = (1 + (6 + 3 + 2) + (3 + 1) * 1/8M
 *    = 16 * 1/8M = 2us 
 *    Baud Rate = 1/2us = 500Kbps 
 * 3. configure 1MB = 8 CAN->RAMn = 32byte
 * 4. MB6 ~ FIFO Rx
 * 5. FIFO receives interrupt 
 * 6. disable frame self reception
 * 7. RFFN = 2,ID filter table = 2*8+8 = 24  
 * 8. ID Acceptance Mode = Format A: 
 * Coder :  djf
 * Date/Time :  2020/07/01 
 * ===================================================
 */

#define MSG_BUF_SIZE        4u    /* 1 Msg Buffer Size : CAN0->RAMn[i] use 4word(1word=4byte). 4word = 2word header, 2word Data*/
#define MB_FIFO_NUM         6u    /* MB Size used for FIFO engine: MB0~5 */
#define MB_FIFO_IDX_RX      6u    /* MB for receiving CAN message*/

void FLEXCAN0_init(void)                   //Classical
{
      
    uint32_t i = 0;

    PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: enable clock to FlexCAN0 */

    CAN0->MCR |= CAN_MCR_SOFTRST_MASK;      //Soft Reset
	CAN0->MCR &= ~CAN_MCR_SOFTRST_MASK;
    
    CAN0->MCR |= CAN_MCR_MDIS_MASK;         /* MDIS=1: Disable module before selecting clock */
    CAN0->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK;  /* CLKSRC=0: Clock Source = oscillator (8 MHz) */
    CAN0->MCR &= ~CAN_MCR_MDIS_MASK;        /* MDIS=0; Enable the FlexCAN module. (Sets FRZ, HALT)	*/  
    // After the clock source is selected and the module is enabled (MCR[MDIS] bit negated), FlexCAN automatically enters Freeze mode. In Freeze mode
    // CAN0->MCR |= CAN_MCR_FRZ_MASK;          /*(Sets FRZ, HALT)	*/ 
    while (!((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)) {
   }
      
    // Step1: Initialize MCR
    CAN0->MCR |= CAN_MCR_IRMQ_MASK // a: IRMQ=1, enable the individual filtering per MB and reception queue features            
              | CAN_MCR_WRNEN_MASK // b: WRNEN=1, enable the warning interrupts
              | CAN_MCR_SRXDIS_MASK // c: SRXDIS=1, disable frame self reception
              | CAN_MCR_RFEN_MASK // d: RFEN=1, Enable the Rx FIFO, MBs 0 to 5 cannot be used for normal reception and transmission(they have been uesed for the FIFO engine)
              // e: DMA=0, dont use DMA
              // f: PNET_EN=0, dont use pretended networking
              | CAN_MCR_AEN_MASK// g: AEN=1, use Tx Abort mechanism
              | CAN_MCR_LPRIOEN_MASK   // h: PRIOEN=1, Local Priority enabled          
              | CAN_MCR_IDAM(0)// IDAM=0, ID Acceptance Mode=Format A: One full ID (standard and extended) per ID filter table element.
              | CAN_MCR_MAXMB(32); // MAXMB = Rx FIFO + ID filter table space(CTRL2[REFN]), default=16             
    
    // Step2: Initialize CTRL1 or CBT
    // The CAN bit variables in CTRL1 and in CBT are stored in the same register.
    // Configure for CAN bit rate = 500 Kbps, 16 time quanta for 1 bit
    CAN0->CTRL1 |= CAN_CTRL1_PRESDIV(0)  // Tq = fcanclk / prediv = 8MHz / 1 = 8MHz
                | CAN_CTRL1_RJW(3)  // RJW: since Phase_Seg2 >=4, RJW+1=4 so RJW=3.
                | CAN_CTRL1_PSEG1(3)  // Phase Segment 1 = PSEG1 + 1
                | CAN_CTRL1_PSEG2(3)  // Phase Segment 2 = PSEG2 + 1
                | CAN_CTRL1_PROPSEG(6)  // Propagation Segment = PROPSEG + 1
                | CAN_CTRL1_SMP(1)    
                | CAN_CTRL1_LBUF(1);   // LBUF=1, Lowest number buffer is transmitted first.(MCR[LPRIOEN] + LBUF <= transmit priority)
                                   
    // Step3: Initialize the message buffers    
    // MB & Rx Individual Mask registers are not affected by reset, so they are not initialized automatically.
    // payload=8, MB0~5 used for FIFO engine(contains message received but not read)
    // CAN0: clear 32 message buffer x 4 words/msg, buf = 128 words
    // CAN0 contains 32MBs         
    for(
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/144618
推荐阅读
相关标签
  

闽ICP备14008679号