以下为我的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_SIZE20 #define RX_DMA_LEN RADIO_RX_SIZE #define MRFI_DMA_CHAN 0 #define MRFI_DMA_TX1 #define ABORT0x80 #define RADIO_SFSTXON 0 #define RADIO_SCAL0x01 #define RADIO_SRX0x02 #define RADIO_STX0x03 #define RADIO_SIDLE0x04 #define RADIO_SNOP0x0A #define RXTX_SWITCH0x15 #define RX0x0D #define IDLE0x01 #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 Disableif(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 statememset(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 EnableRFST = 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; }
liu qiang:
这个问题现在估计不是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(); }