TI中文支持网
TI专业的中文技术问题搜集分享网站

DMA 多通道发送CAN 数据

Ken,

如下是DAM CAN1 IF1发送数据, 请帮我查看寄存器配置是否出现问题?关于IFUEy寄存器 DATASHEET 好像没有说明?

/* USER CODE BEGIN (0) */
#include "rti.h"
#include "can.h"
#include "sys_dma.h"
/* USER CODE END */

/* Include Files */

#include "sys_common.h"

/* USER CODE BEGIN (1) */
#define D_SIZE      8

uint8 TX_DATA1[D_SIZE]={0x30,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8};     /* transmit buffer in sys ram */
uint8 TX_DATA2[D_SIZE]={0x30,0x03,14,15,16,17,18};                    /* transmit buffer in sys ram */
uint8 TX_DATA3[D_SIZE]={21,22,23,24,25,26,27,28};                     /* transmit buffer in sys ram */
uint8 RX_DATA1[D_SIZE]= {0};                                          /* receive  buffer in sys ram */
uint8 RX_DATA2[D_SIZE]= {0};                                          /* receive  buffer in sys ram */
uint8 RX_DATA3[D_SIZE]= {0};

/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
uint32 DMAFlag=0x00;
uint32 DMA_Comp_Flag;
uint32 timer0 = 0;
uint32 CpuCount = 0;
uint8  senderFlag = 0;
g_dmaCTRL g_dmaCTRLPKT;    /* dma control packet configuration stack */

void dmaConfigCtrlRxPacket(uint32 sadd,uint32 dadd,uint32 dsize);
/* USER CODE END */

void main(void)
{
/* USER CODE BEGIN (3) */
    rtiInit();
    rtiStartCounter(rtiCOUNTER_BLOCK0);
    rtiDisableNotification(rtiNOTIFICATION_COMPARE0);
    canInit();
    _enable_IRQ();
      canREG1->CTL |= (uint32)(1<<18);           // enable DMA for IF2
    dmaReqAssign(DMA_CH1, 8);                  // DMA Configuration and Enable DMA
    dmaConfigCtrlRxPacket((uint32)(&TX_DATA1), (uint32)(&(canREG1->IF1DATx[0])), 1);
    dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT);   // setting dma control packets for transmit
    dmaSetChEnable(DMA_CH1, DMA_HW);
    dmaEnableInterrupt(DMA_CH1, FTC);                     // Enable Interrupt after reception of data

    while(1)
    {
          CpuCount = canIsTxMessagePending(canREG1, canMESSAGE_BOX1);
    }

/* USER CODE END */
}

/* USER CODE BEGIN (4) */
#pragma WEAK(rtiNotification)
void rtiNotification(uint32 notification)
{
/*  enter user code between the USER CODE BEGIN and USER CODE END. */
/* USER CODE BEGIN (9) */
/* Reset the Flag */
    timer0 ++;
}

void dmaConfigCtrlRxPacket(uint32 sadd,uint32 dadd,uint32 dsize)
{
    g_dmaCTRLPKT.SADD      = sadd;              /* source address             */
    g_dmaCTRLPKT.DADD      = dadd;              /* destination  address       */
    g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
    g_dmaCTRLPKT.FRCNT     = 1;                 /* frame count                */
    g_dmaCTRLPKT.ELCNT     = dsize;             /* element count              */
    g_dmaCTRLPKT.ELDOFFSET = 0;                 /* element destination offset */
    g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element source offset      */
    g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
    g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame source offset        */
    g_dmaCTRLPKT.PORTASGN  = 4;                 /* port b                     */
    g_dmaCTRLPKT.RDSIZE    = ACCESS_64_BIT;     /* read size                  */
    g_dmaCTRLPKT.WRSIZE    = ACCESS_64_BIT;     /* write size                 */
    g_dmaCTRLPKT.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
    g_dmaCTRLPKT.ADDMODERD = ADDR_FIXED;        /* address mode read          */
    g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED;        /* address mode write         */
    g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_ON;      /* autoinit                   */
}
/* USER CODE END */

Ken Wang:

sam,

    canREG1->CTL |= (uint32)(1<<18);           // enable DMA for IF2    dmaReqAssign(DMA_CH1, 8);                  // DMA Configuration and Enable DMA    dmaConfigCtrlRxPacket((uint32)(&TX_DATA1), (uint32)(&(canREG1->IF1DATx[0])), 1);

 这几句话好像有点问题,你第一句设置的是enable IF2的DMA,后弦设置的硬件触发是request line是DCAN1 IF1。 是不是改下试试看。

谢谢

Sam:

回复 Ken Wang:

Ken,

不好意思,canREG1->CTL |= (uint32)(1<<18); 就使能DMA IF1, 注释出现的笔误;

dmaReqAssign(DMA_CH1, 8);    // can1 的IF1 对应的request line 是8,

测试后不成功。。

Ken Wang:

回复 Sam:

sam,

   我想了一下,我们用DMA去触发CAN总线的传输,这个其实不是太好操作。具体原因是:

1. 我们操作的DMA触发CAN的终端地址是IF1DATA[0],没有设置其他一些参数,包括你需要选择哪个messagebox。这个是个很重要的参数,因为你不设置对的messagebox,就不能通过相应的CANID把数据发出去,同时接收端也不一定能接到你的数据。

2.但我们用DMA去触发DMA的接收,这个操作确实可行的,因为它已经经过了CAN报文的解析,到达IF3里面的只是纯的数据了,这样就不会出错。

所以说用DMA去触发CAN总线的操作,不是太有效。当然也不是说完全不可以,有一个解决办法就是,你手动的设置数据发出的messagebox number。我刚试了一下,这个办法能行,但是效率太低。

   具体的设置如下:

                       canREG2->IF1NO = canMESSAGE_BOX1;

所以还是建议你考虑一下,是不是不用DMA去触发CAN的数据发送,想想其他的办法解决一下。

有什么想法,我们再交流。

谢谢

Sam:

回复 Ken Wang:

Ken,

如果DMA发送数据部占优势的话, 那先就不考虑DMA发送数据了..

目前还有个问题关于DMA channel:

如果用DCAN1 DMA 接收数据 需要设置成dmaReqAssign(DMA_CH0, 4); 因为CAN1对应 request line 是 4 ..

如果用DCAN2 DMA 接收数据 需要设置成dmaReqAssign(DMA_CH1, 16); 因为CAN1对应 request line 是 16 ..

再这里我想问DMA_CH0这个通道的概念..DMA 有32个channel.  我大胆的猜想, 如果CAN1 将32个通道同时对应一个request line 4,  这样操作可行?

如果可行是不是传输数据更快?

Ken Wang:

回复 Sam:

Sam,

    DMA channel只是为了方便设置DMA通道的优先级,因为我们芯片支持16个可独立配置的通道,如果一个系统里面用到了多个通道的话。他们在处理数据时,需要有相关的优先级仲裁,才能保证信息不被丢失。

   默认情况下,channel的ID越小,优先级越大,当然这个也可以通过相关的寄存器设置。

如果你将32个通道连接到一个request line的话,这个数据传输可能会变慢。因为你32个通道都有数据发送,他们之间如果对应一个DMA request line的话,每一个CAN报文都需要等一个DMA传输结束后,才能去发送数据,然后在通过DMA去发送。还有一个问题就是,你需要在完成一次DMA操作后,再去配置新的DMA的寄存器,修改终端地址,这样效率会很低。

谢谢

Sam:

回复 Ken Wang:

Ken,

那就是一个CAN 对应一个channel, 每个channel对应一个request line, 每个源地址对应一个终端地址。这样是最常用的方式。

如果用多channel 来接收数据的话,是不是意义不大. 因为每个CAN 只有一个源地址IF3DATx?  再去不对切换channel和更改终端地址。。有点得不偿失?

效率也是没有提高。。反而再不断切换和修改Register 而浪费时间。。我理解的对吗?

Sam:

回复 Ken Wang:

Ken,

好的。明白了。谢谢!!

赞(0)
未经允许不得转载:TI中文支持网 » DMA 多通道发送CAN 数据
分享到: 更多 (0)