微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI无线射频设计 > CC1110的DMA收发问题

CC1110的DMA收发问题

时间:12-23 整理:3721RD 点击:
以下为我的DMA收发代码,现在的问题是,能接收不同长度的数据包,但是不能发送不同长度的数据包,
比如我现在收发19个字节的数据时没问题的,但是发送少于19个字节的数据,接收端始终接收不到,
接收端是CC1101,TI的大咖看看我这段DMA收发程序是不是有误的地方,
奇怪的是19个字节就一点问题没有

#include "string.h"
#include "comdef.h"
#include "ioCC1110.h"
#include "dma.h"
#include "radio.h"
#include "RingBuffer.h"

#define RADIO_RX_SIZE  64
#define RADIO_TX_SIZE  64
#define RADIO_FIFO_SIZE  64
#define RF_PACK_SIZE     20

#define RX_DMA_LEN  RADIO_RX_SIZE

#define MRFI_DMA_CHAN  0
#define MRFI_DMA_TX    1

#define ABORT          0x80

#define RADIO_SFSTXON  0
#define RADIO_SCAL    0x01
#define RADIO_SRX     0x02
#define RADIO_STX     0x03
#define RADIO_SIDLE   0x04
#define RADIO_SNOP    0x0A

#define RXTX_SWITCH   0x15
#define RX            0x0D
#define IDLE          0x01


#define MRFI_STROBE_IDLE_AND_WAIT()  \
{                                    \
  RFST = RADIO_SIDLE;                      \
  while (MARCSTATE != IDLE) ;        \
}
static DMA_DESC dma_cfg,dma_cfg_tx;
static uint8_t rf_state;

enum {RF_UNDEF=1,RF_RX,RF_TX,RF_SCAL,RF_IDLE};

static BYTE_RING_BUFFER rx_loop,tx_loop;

static uint8_t Rxbuffer[RADIO_RX_SIZE];
static uint8_t Txbuffer[RADIO_TX_SIZE];
static uint8_t rx_fifo[RADIO_FIFO_SIZE];
static uint8_t tx_fifo[RADIO_FIFO_SIZE];


RCALL_TYPE rx_rcall,tx_rcall;


void radio_rxOn(void);



static void radio_RxModeOff(void)
{
  /*disable receive interrupts */
  RFIM &= ~(1<<4);           /* Clear the interrupt at the source */

  /* turn off radio */
  MRFI_STROBE_IDLE_AND_WAIT();

  /* Abort any ongoing DMA transfer */
  DMAARM = ABORT | DEF_B8( MRFI_DMA_CHAN )|DEF_B8( MRFI_DMA_TX);
  /* Clear any pending DMA interrupts */
  DMAIRQ &= ~(DEF_B8(MRFI_DMA_CHAN)|DEF_B8( MRFI_DMA_TX));

  /* clear receive interrupt */
  S1CON = 0; /* Clear MCU interrupt flag */
  RFIF = ~(1<<4);           /* Clear the interrupt at the source */
  IEN1 &=0xFE;   //DMA interrupt Disable
}

#pragma vector = RF_VECTOR
__interrupt void rf_ISR(void)
{
    uint8_t i;
    S1CON = 0;              /* Clear MCU interrupt flag */
    RFIM &= ~(1<<4);
    IEN2 &= 0xFE;
    i = RFIF;
    RFIF &= ~i;       /* Clear the interrupt at the source */
    
    i = byteRingGetCount(&tx_loop);
        if(i>0){
            if(i<RF_PACK_SIZE){
                tx_fifo[0] = byteRingRead(&tx_loop,&tx_fifo[1],i);
            }
            else{
                tx_fifo[0] = byteRingRead(&tx_loop,&tx_fifo[1],(RF_PACK_SIZE-1));
            }
            DMAARM |= DEF_B8( MRFI_DMA_CHAN );
            DMAIRQ = ~DEF_B8(MRFI_DMA_CHAN);
            S1CON = 0; /* Clear MCU interrupt flag */
            /* send strobe to enter receive mode */
            RFST = RADIO_STX;
            /* enable "receive/transmit done" interrupts */
            RFIM |= (1<<4);
            IEN2 |= 1;
        }    
        else{
            radio_RxModeOff();
            if(tx_rcall!=DEF_NULL){
                (*tx_rcall)();
            }
        }
}


#pragma vector = DMA_VECTOR
__interrupt void rf_isr_handler(void)
{
    
    DMAIRQ &= ~DEF_B8(MRFI_DMA_CHAN);
    IRCON &= ~DEF_B8(0);
  //  IEN1 &=0xFE;   //DMA interrupt Disable
    
    if(rf_state==RF_RX){
        byteRingWrite(&rx_loop,&rx_fifo[1],rx_fifo[0]);
        radio_RxModeOff();
        if(rx_rcall!=DEF_NULL){
            (*rx_rcall)();
        }
    }
}



void dma_init(void)
{
    DMAIRQ &= ~(DEF_B8(MRFI_DMA_CHAN)|DEF_B8(MRFI_DMA_TX));
    
    /* tx dma set */
    dma_cfg_tx.SRCADDRH= HIGH_BYTE_OF_WORD(&tx_fifo[0]);
    dma_cfg_tx.SRCADDRL= LOW_BYTE_OF_WORD(&tx_fifo[0]);
    dma_cfg_tx.DESTADDRH= HIGH_BYTE_OF_WORD(&X_RFD);
    dma_cfg_tx.DESTADDRL= LOW_BYTE_OF_WORD(&X_RFD);
    dma_cfg_tx.VLEN = DMA_VLEN_1_P_VALOFFIRST;
    dma_cfg_tx.LENH = HIGH_BYTE_OF_WORD(RADIO_FIFO_SIZE)&0x1F;
    dma_cfg_tx.LENL = LOW_BYTE_OF_WORD(RADIO_FIFO_SIZE);
    dma_cfg_tx.WORDSIZE = DMA_WORDSIZE_BYTE;
    dma_cfg_tx.TMODE = DMA_TMODE_SINGLE;
    dma_cfg_tx.TRIG = DMA_TRIG_RADIO;
    dma_cfg_tx.SRCINC = DMA_DESTINC_1;
    dma_cfg_tx.DESTINC = DMA_SRCINC_0;
    dma_cfg_tx.IRQMASK = DMA_IRQMASK_DISABLE;
    dma_cfg_tx.M8 = DMA_M8_USE_8_BITS;
    dma_cfg_tx.PRIORITY = DMA_PRI_GUARANTEED;
    
    
    /* rx dma set */
    dma_cfg.SRCADDRH= HIGH_BYTE_OF_WORD(&X_RFD);
    dma_cfg.SRCADDRL= LOW_BYTE_OF_WORD(&X_RFD);
    dma_cfg.DESTADDRH= HIGH_BYTE_OF_WORD(&rx_fifo[0]);
    dma_cfg.DESTADDRL= LOW_BYTE_OF_WORD(&rx_fifo[0]);
    dma_cfg.VLEN = DMA_VLEN_1_P_VALOFFIRST;
    dma_cfg.LENH = HIGH_BYTE_OF_WORD(RADIO_FIFO_SIZE)&0x1F;
    dma_cfg.LENL = 0x14;//LOW_BYTE_OF_WORD(RADIO_FIFO_SIZE);
    dma_cfg.WORDSIZE = DMA_WORDSIZE_BYTE;
    dma_cfg.TMODE = DMA_TMODE_SINGLE;
    dma_cfg.TRIG = DMA_TRIG_RADIO;
    dma_cfg.SRCINC = DMA_SRCINC_0;
    dma_cfg.DESTINC = DMA_DESTINC_1;
    dma_cfg.IRQMASK = DMA_IRQMASK_ENABLE;//DMA_IRQMASK_DISABLE;
    dma_cfg.M8 = DMA_M8_USE_8_BITS;
    dma_cfg.PRIORITY = DMA_PRI_HIGH;
    
    DMA0CFGH = HIGH_BYTE_OF_WORD( &dma_cfg );
    DMA0CFGL = LOW_BYTE_OF_WORD ( &dma_cfg );
    
    DMA1CFGH = HIGH_BYTE_OF_WORD( &dma_cfg_tx );
    DMA1CFGL = LOW_BYTE_OF_WORD ( &dma_cfg_tx );
    
    DMAARM = ABORT | DEF_B8( MRFI_DMA_CHAN )|DEF_B8(MRFI_DMA_TX);
  //  DMAARM |= DEF_B8(MRFI_DMA_CHAN);
 //   DMAARM |= DEF_B8(MRFI_DMA_TX);
    /* Abort any ongoing DMA transfer */
    
}

void radio_rxOn(void)
{
    /* Clear interrupts */
    //  S1CON &= ~(RFIF_1 | RFIF_0); /* Clear MCU interrupt flag */
    S1CON = 0; /* Clear MCU interrupt flag */
    RFIF &= ~(1<<4);           /* Clear the interrupt at the source */
    
     //MRFI_STROBE_IDLE_AND_WAIT();      // put the radio in a known state
    memset(rx_fifo, 0x00, RADIO_FIFO_SIZE);
    /* Clear any pending DMA interrupts */
    DMAIRQ &= ~DEF_B8(MRFI_DMA_CHAN);
    
    /* Abort any ongoing DMA transfer */
   // DMAARM = ABORT | DEF_B8( MRFI_DMA_CHAN );
    DMAARM = DEF_B8( MRFI_DMA_CHAN );
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
  //  DMAREQ |= DEF_B8(MRFI_DMA_CHAN);
    /* send strobe to enter receive mode */
    IEN1 |=1;   //DMA interrupt Enable
    RFST = RADIO_SRX;

    
    rf_state = RF_RX;
}

void radio_txOn(uint8_t *tsrc,uint8_t len)
{
    radio_RxModeOff();
    tx_fifo[0] = len;
    memcpy(&tx_fifo[1],tsrc,len);
    DMAARM = DEF_B8(MRFI_DMA_TX);
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    asm("NOP"); asm("NOP");
    RFST = RADIO_STX;
    /* enable "receive/transmit done" interrupts */
    RFIM |= (1<<4);
    IEN2 |= 1;
    rf_state = RF_TX;
 
}

void radio_send(uint8_t *tsrc,uint8_t len)
{
    if(rf_state==RF_TX){
      //  ENTER_CRITICAL;
        byteRingWrite(&tx_loop,tsrc,len); 
     //   EXIT_CRITICAL;
    }
    else{
        if(len<RF_PACK_SIZE){
            radio_txOn(tsrc,len); 
        }
        else{
            radio_txOn(tsrc,RF_PACK_SIZE-1);
       //     ENTER_CRITICAL;
            byteRingWrite(&tx_loop,&tsrc[RF_PACK_SIZE],len-(RF_PACK_SIZE-1)); 
       //     EXIT_CRITICAL;
        }
    }
}
uint8_t radio_read(uint8_t *out_src,uint8_t len)
{
    uint8_t i;
 //   ENTER_CRITICAL;
    i = (uint8_t)byteRingGetCount(&rx_loop);
    if(i>0){
       i = byteRingRead(&rx_loop,out_src,len);
    }
//    EXIT_CRITICAL;
    return i;
}


void radio_pn9(void)
{
    PKTCTRL0  = 0x64;   // Packet automation control.
    RFST = RADIO_SIDLE;
    while((MARCSTATE&0x1f)!=0x01);
    RFST = RADIO_STX;
    while(1);
}

void set_rcall(RCALL_TYPE arg)
{
  if(arg){
        rx_rcall = arg;
  }
}

void set_tcall(RCALL_TYPE arg)
{
  if(arg){
        tx_rcall = arg;
  }
}

void radio_init(uint8_t ch)
{
    uint32_t loop;
    
    rx_rcall = DEF_NULL;
    tx_rcall = DEF_NULL;
    memset(Rxbuffer, 0x00, RADIO_RX_SIZE);
    memset(Txbuffer, 0x00, RADIO_TX_SIZE);
    byteRingBufInit(&rx_loop,Rxbuffer,RADIO_RX_SIZE);
    byteRingBufInit(&tx_loop,Txbuffer,RADIO_TX_SIZE);

    dma_init();

    /* Setup radio with settings from SmartRF?Studio. The default settings are
     * used, except that "unmodulated" is chosen in the "Simple RX tab". This
     * results in an umodulated carrier with a frequency of approx. 2.433 GHz.
     */
    FSCTRL1   = 0x06;   // Frequency synthesizer control.
    FSCTRL0   = 0x00;   // Frequency synthesizer control.
    FREQ2     = 0x10;   // Frequency control word, high byte.
    FREQ1     = 0x89;   // Frequency control word, middle byte.
    FREQ0     = 0xD8;   // Frequency control word, low byte.
    MDMCFG4   = 0xCA;   // Modem configuration.
    MDMCFG3   = 0x83;   // Modem configuration.
    MDMCFG2   = 0x03;   // Modem configuration.
    MDMCFG1   = 0xA2;   // Modem configuration.
    MDMCFG0   = 0xF8;   // Modem configuration.
    CHANNR    = ch;     // Channel number.
    DEVIATN   = 0x34;   // Modem deviation setting (when FSK modulation is enabled).
    FREND1    = 0x56;   // Front end RX configuration.
    FREND0    = 0x10;   // Front end RX configuration.
    MCSM2     = 0x07;
    MCSM1     = 0x30;
    MCSM0     = 0x18;   // Main Radio Control State Machine configuration.
    FOCCFG    = 0x16;   // Frequency Offset Compensation Configuration.
    BSCFG     = 0x6C;   // Bit synchronization Configuration.
    AGCCTRL2  = 0x43;   // AGC control.
    AGCCTRL1  = 0x40;   // AGC control.
    AGCCTRL0  = 0x91;   // AGC control.
    FSCAL3    = 0xE9;   // Frequency synthesizer calibration.
    FSCAL2    = 0x2A;   // Frequency synthesizer calibration.
    FSCAL1    = 0x00;   // Frequency synthesizer calibration.
    FSCAL0    = 0x1F;   // Frequency synthesizer calibration.
    TEST2     = 0x81;   // Various test settings.
    TEST1     = 0x35;   // Various test settings.
    TEST0     = 0x0B;   // Various test settings.
    PA_TABLE0 = 0xC0;   // PA output power setting.
    PKTCTRL1  = 0x04;   // Packet automation control.
    PKTCTRL0  = 0x44;   // Packet automation control.
    ADDR      = 0x00;   // Device address.
    PKTLEN    = 0x14;   // Packet length.

    /* Settings not from SmartRF?Studio. Setting both sync word registers to
     * 0xAA = 0b10101010, i.e., the same as the preamble pattern. Not necessary,
     * but gives control of what the radio attempts to transmit.
     */
    SYNC1     = 0xD3;
    SYNC0     = 0x2C;
    RFIF = 0;    
    RFST = RADIO_SIDLE;
    RFST = RADIO_SCAL;
    loop = 5000;
    while(loop--);

    rf_state = RF_IDLE; 
   // RFTXRXIE = 1;
  //  IEN2     |= 1;
}

这个问题现在估计不是DMA的问题了,应该还是radio的问题了,我现在用的是定长发送,用了芯片的硬件包处理,包定长为20字节,我接收端是CC1101,也是定长数据包,所以发送一个20字节的数据包是可以的,但是发送少于20字节的数据包就不行了,接收端CC1101如果包不够20字节就收不到,所以我现在不用DMA来发,用直接发RFD端口的方法来发送,保证每个数据包发出去20个字节,这样发送全速运行的时候少于20字节的数据还是接收不到,但是在红字处设置

一个断点暂停下,再运行就发送,接收端就接收ok了,一直找不到原因

void radio_txOn(uint8_t *tsrc,uint8_t len)
{
    uint8_t i;
    RFTXRXIF = 0; //这里设置一个断点暂停下,少于20字节的数据发送是可以
    RFIF &=~IRQ_DONE;
    if(len<=64){
        STX();
        while(RFTXRXIF==0);  //等待发送结束
        RFTXRXIF  = 0;
        RFD = len;
        
        for(i=0;i<19;i++){
            while(RFTXRXIF==0);  //等待发送结束
            RFTXRXIF  = 0;
            RFD = *tsrc++;
        }
        while(!(RFIF & IRQ_DONE));
        RFIF &= ~IRQ_DONE;
    }
    /* turn off radio */
    MRFI_STROBE_IDLE_AND_WAIT();
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top