#1楼主:对CC2510的DMA配置有点不明白!
文章发表于:2008-04-01 10:36
大家好!这段时间在看DMA的配置。编写及调试用DMA去配置RF并发射,可是还是失败了,我不知道问题出在那里!所以把我的过程贴出来,希望高手能够帮我分析一下,也希望和我一样对这个配置有问题的朋友能够看到这个贴能够快速 地组建自己的DMA并发射成功。
我的流程是这样的:先配置要发射的频率及RF参数,然后配置DMA。最后启动DMA,但是结果总是在 while(!tx_status);停留。RF没有产生中断。我不知道是DMA配置错误了还是其它的问题。希望前辈们能够多多帮忙。如果那位大侠有DMA的操作例程的话希望,希望能够得到你们的帮助,转发一个给我!谢谢!我的邮件是:huwa20@163.com
不胜感激!
typedef struct {
BYTE SRCADDRH;
BYTE SRCADDRL;
BYTE DESTADDRH;
BYTE DESTADDRL;
BYTE VLEN : 3;
BYTE LENH : 5;
BYTE LENL : 8;
BYTE WORDSIZE : 1;
BYTE TMODE : 2;
BYTE TRIG : 5;
BYTE SRCINC : 2;
BYTE DESTINC : 2;
BYTE IRQMASK : 1;
BYTE M8 : 1;
BYTE PRIORITY : 2;
} DMA_DESC;
void dmaRadioSetup(BYTE mode)
{
// Some configuration that are common for both TX and RX:
// CPU has priority over DMA
// Use 8 bits for transfer count
// No DMA interrupt when done
// DMA triggers on radio
// Single transfer per trigger.
// One byte is transferred each time.
dmaConfig.PRIORITY = DMA_PRI_LOW;
dmaConfig.M8 = DMA_M8_USE_8_BITS;
dmaConfig.IRQMASK = DMA_IRQMASK_DISABLE;
dmaConfig.TRIG = DMA_TRIG_RADIO;
dmaConfig.TMODE = DMA_TMODE_SINGLE;
dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE;
if (mode == RADIO_MODE_TX) {
// Transmitter specific DMA settings
// Source: radioPktBuffer
// Destination: RFD register
// Use the first byte read + 1
// Sets the maximum transfer count allowed (length byte + data)
// Data source address is incremented by 1 byte
// Destination address is constant
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, radioPktBuffer);
SET_WORD(dmaConfig.DESTADDRH, dmaConfig.DESTADDRL, &X_RFD);
dmaConfig.VLEN = DMA_VLEN_FIRST_BYTE_P_1;
SET_WORD(dmaConfig.LENH, dmaConfig.LENL, (PACKET_LENGTH + 1));
dmaConfig.SRCINC = DMA_SRCINC_1;
dmaConfig.DESTINC = DMA_DESTINC_0;
}
else if (mode == RADIO_MODE_RX) {
// Receiver specific DMA settings:
// Source: RFD register
// Destination: radioPktBuffer
// Use the first byte read + 3 (incl. 2 status bytes)
// Sets maximum transfer count allowed (length byte + data + 2 status bytes)
// Data source address is constant
// Destination address is incremented by 1 byte for each write
SET_WORD(dmaConfig.SRCADDRH, dmaConfig.SRCADDRL, &X_RFD);
SET_WORD(dmaConfig.DESTADDRH, dmaConfig.DESTADDRL, radioPktBuffer);
dmaConfig.VLEN = DMA_VLEN_FIRST_BYTE_P_3;
SET_WORD(dmaConfig.LENH, dmaConfig.LENL, (PACKET_LENGTH + 3));
dmaConfig.SRCINC = DMA_SRCINC_0;
dmaConfig.DESTINC = DMA_DESTINC_1;
}
// Save pointer to the DMA configuration struct into DMA-channel 0
// configuration registers
SET_WORD(DMA0CFGH, DMA0CFGL, &dmaConfig);
return;
}
#pragma vector = RF_VECTOR
__interrupt void RF_Interrupt()
{
RFIF &= ~IRQ_DONE; // Tx/Rx completed, clear interrupt flag
S1CON &= ~0x03; // Clear the general RFIF interrupt registers
LED = ~LED;
if (mode == RADIO_MODE_RX) {
rx_status = TRUE;
}
else {
tx_status = TRUE;
}
}
#pragma vector = RFTXRX_VECTOR
__interrupt void RFTXRX_Interrupt()
{
}
//=================
#pragma vector = DMA_VECTOR
__interrupt void DMA_Interrupt()
{
}
void main()
{
SET_MAIN_CLOCK_SPEED(CRYSTAL);
halRfSetRadioFrequency(freq);
PKTLEN = 17;
PKTCTRL0 = 0x05;
PKTCTRL1 = 0x04;
// IF frequency
FSCTRL1 = 0x0A;
FSCTRL0 = 0x00;
// filter BW, data rate,
MDMCFG4 = 0x2D;
MDMCFG3 = 0x3B;
// Modulation format, detection level
MDMCFG2 = 0x73;
MDMCFG1 = 0x22;
MDMCFG0 = 0xF8;
// Deviation setting
DEVIATN = 0x00;
// Calibration synth
MCSM2 = 0x07;
MCSM1 = 0x30;
MCSM0 = 0x10;
// Frequency offset compensation configuration
FOCCFG = 0x1D;
// Bit synchronization
BSCFG = 0x1C;
// AGC settings
AGCCTRL2 = 0xC7;
AGCCTRL1 = 0x00;
AGCCTRL0 = 0xB2;
// Front end settings (from SmartRf04)
FREND1 = 0xB6;
FREND0 = 0x10;
// Synth calibration
FSCAL3 = 0xEA;
FSCAL2 = 0x0A;
FSCAL1 = 0x00;
FSCAL0 = 0x11;
// From Smart RF Studio
FOCCFG = 0x1D;
BSCFG = 0x1C;
FSTEST = 0x59;
PTEST = 0x7F;
AGCTEST = 0x3F;
TEST2 = 0x88;
TEST1 = 0x31;
TEST0 = 0x0B;
// Output power
PA_TABLE0 = 0xFF;
// Calibrating synth.
SIDLE();
SCAL();
while(MARCSTATE != 0x01);
MCSM1 = 0x2F;
// SRX();
INT_SETFLAG(INUM_RFTXRX,INT_CLR);
//====================================
dmaRadioSetup(RADIO_MODE_TX);
// Construct the packet to be transmitted in buffer
radioPktBuffer[0] = PACKET_LENGTH; // Length byte
radioPktBuffer[1] = (BYTE) (NETWORK_ID_KEY>>8); // Network identifier
radioPktBuffer[2] = (BYTE) NETWORK_ID_KEY;
// radioPktBuffer[3:6] = 4 byte packet sequence number, written later
// Fill rest of payload with dummy data. Radio is using data whitening.
for (i = 7; i <= PACKET_LENGTH; i++) {
radioPktBuffer[i] = 0xCC;
};
INT_ENABLE(INUM_RF, INT_ON); // Enable RF general interrupt
RFIM = IRQ_DONE; // Mask IRQ_DONE flag only
INT_GLOBAL_ENABLE(INT_ON); // Enable interrupts globally
SET_MAIN_CLOCK_SPEED(CRYSTAL);
Send_Again:
SET_DMA_SOURCE1(dmaConfig,radioPktBuffer);
// Send the packet
RFTXRXIF = 0;
INT_GLOBAL_ENABLE(FALSE);
DMA_ARM_CHANNEL(DMAARM_CHANNEL0);
DMA_ARM_CHANNEL(0);
STX();
INT_GLOBAL_ENABLE(TRUE);
// Wait until the radio transfer is completed,
// and then reset pktSentFlag
while(!tx_status);
tx_status = FALSE;
goto Send_Again;
}