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();
}
