新闻  |   论坛  |   博客  |   在线研讨会
cc2500驱动程序(Atmega16)
0750long | 2009-06-17 12:18:05    阅读:3532   发布文章

cc2500驱动程序(Atmega16)

 

头文件:cc2500.h

#ifndef _CC2500_H
#define _CC2500_H

// CC2500 管脚
#define CC2500_CSn     RF_IO0 // PB4
#define CC2500_GDO0    RF_IO1 // PD2
#define CC2500_GDO2    RF_IO2 // PD3

// 定义数据包
#define CC2500_PKT_LEN  80
typedef struct {
 u8_t buf[CC2500_PKT_LEN];
 u8_t len;
} packet_2500_t;
extern packet_2500_t tx_pkt_2500;
extern packet_2500_t rx_pkt_2500;
extern u8_t rx_state_2500;
extern u8_t rx_flag_2500;

// PATABLE (1 dBm output power)
extern u8_t paTable[];
extern u8_t paTableLen;

void cc_wait(u16_t cycles);

void cc_spi_setup(void);
void cc_spi_write_reg(u8_t addr, u8_t value);
void cc_spi_write_burst_reg(u8_t addr, u8_t *buffer, u8_t count);
u8_t cc_spi_read_reg(u8_t addr);
void cc_spi_read_burst_reg(u8_t addr, u8_t *buffer, u8_t count);
u8_t cc_spi_read_status(u8_t addr);
void cc_spi_strobe(u8_t strobe);
void cc_powerup_reset(void);

void cc_write_settings(void);
void cc_send_packet(u8_t *tx_buf, u8_t size);
u8_t cc_receive_packet(u8_t *rx_buf, u8_t *length);

// test function
void cc_test(void);

#endif

 

实现代码:cc2500.c

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "common.h"
#include "ccxxx0_reg.h"
#include "cc2500.h"
#include "key.h"

// 数据包
packet_2500_t tx_pkt_2500;
packet_2500_t rx_pkt_2500;
u8_t rx_state_2500;
u8_t rx_flag_2500;

void cc_wait(u16_t cycles)
{
    while (cycles > 6)
        cycles -= 6;
}

// cc2500 外部管脚配置
void cc_spi_setup(void)
{
 DDRB |= CC2500_CSn;
 PORTB |= CC2500_CSn;
 PORTD |= CC2500_GDO0; // 使能上拉

 // 配置SPI总线
 //SPSR |= (1<<SPI2X); // 设置SPI时钟倍速
 SPCR |= (1<<SPE)|(1<<MSTR);  // 使能SPI接口,主机模式

 cli(); // 清所有中断
 MCUCR |= 0x02; // INT0下降沿触发
 GICR |= 0x40; // 使能INT0
}

void cc_spi_write_reg(u8_t addr, u8_t value)
{
    // CS enable
    PORTB &= ~CC2500_CSn;
    // wait for CCxxxx ready
    while (PINB&SPI_MISO);
    // Clear flag
    SPSR = 0x00;
    // Send address
    SPDR = addr;
    // Wait for TX to finish
    while (!(SPSR & (1<<SPIF))) ;
    cc_wait(75);
    // Clear flag
    SPSR = 0x00;
    // Load data for TX after addr
    SPDR = value;
    // Wait for end of addr TX
    while (!(SPSR & (1<<SPIF))) ;
    cc_wait(75);
    // CS disable
    PORTB |= CC2500_CSn;
}

void cc_spi_write_burst_reg(u8_t addr, u8_t *buffer, u8_t count)
{
    u8_t i;

    // CS enable
    PORTB &= ~CC2500_CSn;
    // Wait for CCxxxx ready
    while (PINB&SPI_MISO) ;
    // Clear flag
    SPSR = 0x00;
    // Send address
    SPDR = addr|TI_CCxxx0_WRITE_BURST;
    // Wait for TX to finish
    while (!(SPSR & (1<<SPIF))) ;
    for (i=0; i<count; i++) {
        // Clear flag
     SPSR = 0x00;
        SPDR = buffer[i];
        while (!(SPSR & (1<<SPIF))) ;
        cc_wait(30);
        cc_wait(30);
    }
    // Clear flag
    SPSR = 0x00;
    // CS disable
    PORTB |= CC2500_CSn;
}

u8_t cc_spi_read_reg(u8_t addr)
{
    u8_t x;

    // CS enable
    PORTB &= ~CC2500_CSn;
    // Wait for CCxxxx ready,
    while (PINB&SPI_MISO) ;
    // Clear flag set during addr TX
    SPSR = 0x00;
    // Send Address
    SPDR = addr|TI_CCxxx0_READ_SINGLE;
    // Wait for TXBUF ready
    while (!(SPSR & (1<<SPIF))) ;
    cc_wait(75);
    // Clear flag set during addr TX
    SPSR = 0x00;
    // Load dummy byte for TX after addr
    SPDR = 0;
    // Wait for end of dymmy byte TX
    while (!(SPSR & (1<<SPIF))) ;
    cc_wait(75);
    // Read data
    x = SPDR;
    cc_wait(45);
    cc_wait(45);

    // CS disable
    PORTB |= CC2500_CSn;

    return x;
}

void cc_spi_read_burst_reg(u8_t addr, u8_t *buffer, u8_t count)
{
    u8_t i;

    // CS enable
    PORTB &= ~CC2500_CSn;
    // Wait for CCxxxx ready
    while (PINB&SPI_MISO) ;
    // clear flag
    SPSR = 0x00;
    // Send address
    SPDR = addr|TI_CCxxx0_READ_BURST;
    // Wait for txbuf ready
    while (!(SPSR & (1<<SPIF))) ;
    cc_wait(60);
    for (i=0; i<count; i++) {
     SPSR = 0x00; // Clear flag
        // Initiate next data RX, meanwhile
        SPDR = 0;
        // wair for end of 1st data byte TX
        while (!(SPSR & (1<<SPIF))) ;
        cc_wait(30);
        buffer[i] = SPDR;
    }

    // Clear flag
    SPSR = 0x00;
    // CS diable
    PORTB |= CC2500_CSn;
}

u8_t cc_spi_read_status(u8_t addr)
{
    u8_t x;

    // CS enable
    PORTB &= ~CC2500_CSn;
    // Wait for CCxxxx ready
    while (PINB&SPI_MISO) ;
    // Clear flag set during last write
    SPSR = 0x00;
    // Send address
    SPDR = addr|TI_CCxxx0_READ_BURST;
    // Wait for TX to finish
    while (!(SPSR & (1<<SPIF))) ;
    // Clear flag set during last write
    SPSR = 0x00;
    // Dummy write so we can read data
    SPDR = 0;
    // Wait for RX to finish
    while (!(SPSR & (1<<SPIF))) ;
    cc_wait(45);
    cc_wait(45);
    // Read data
    x = SPDR;
    // CS disable
    PORTB |= CC2500_CSn;

    return x;
}

void cc_spi_strobe(u8_t strobe)
{
    // CS enable
 PORTB &= ~CC2500_CSn;
    // Wait for CCxxxx ready
 while (PINB&SPI_MISO) ;
    // Clear flag set during last write
 SPSR = 0x00;
    // Send strobe
    SPDR = strobe;
    // Wait for TX to finish
    while (!(SPSR & (1<<SPIF))) ;
    // CS disable
    PORTB |= CC2500_CSn;
}

void cc_powerup_reset(void)
{
    // CS disable
 PORTB |= CC2500_CSn;
    cc_wait(30);
    // CS enable
    PORTB &= ~CC2500_CSn;
    cc_wait(30);
    // CS disable
    PORTB |= CC2500_CSn;
    cc_wait(45);

    // CS enable
    PORTB &= ~CC2500_CSn;
    // Wait for CCxxxx ready
    while (PINB&SPI_MISO) ;
    // clear flag
    SPSR = 0x00;
    // reset CCxxxx chip
    SPDR = TI_CCxxx0_SRES;
    // Wait for end of addr TX
    while (!(SPSR & (1<<SPIF))) ;
    cc_wait(45);
    cc_wait(45);
    cc_wait(45);
    // CS disable
    PORTB |= CC2500_CSn;
}

// CC2500
// Product = CC2500
// Crystal accuracy = 40 ppm
// X-tal frequency = 26 MHz
// RF output power = 0 dBm
// RX filterbandwidth = 540.000000 kHz
// Deviation = 0.000000
// Return state:  Return to RX state upon leaving either TX or RX
// Datarate = 250.000000 kbps
// Modulation = (7) MSK
// Manchester enable = (0) Manchester disabled
// RF Frequency = 2433.000000 MHz
// Channel spacing = 199.950000 kHz
// Channel number = 0
// Optimization = Sensitivity
// Sync mode = (3) 30/32 sync word bits detected
// Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX
// CRC operation = (1) CRC calculation in TX and CRC check in RX enabled
// Forward Error Correction = (0) FEC disabled
// Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word.
// Packetlength = 255
// Preamble count = (2)  4 bytes
// Append status = 1
// Address check = (0) No address check
// FIFO autoflush = 0
// Device address = 0
// GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet
// GDO2 signal selection = (11) Serial Clock
void cc_write_settings(void)
{
#if 0
    // Write register settings
    cc_spi_write_reg(TI_CCxxx0_IOCFG2,   0x0B);  // GDO2 output pin config.
 //cc_spi_write_reg(TI_CCxxx0_IOCFG2,   0x3A);  // GDO2 output pin config.
    cc_spi_write_reg(TI_CCxxx0_IOCFG0,   0x06);  // GDO0 output pin config.
    cc_spi_write_reg(TI_CCxxx0_PKTLEN,   0xFF);  // Packet length.
    cc_spi_write_reg(TI_CCxxx0_PKTCTRL1, 0x05);  // Packet automation control.
    cc_spi_write_reg(TI_CCxxx0_PKTCTRL0, 0x05);  // Packet automation control.
    cc_spi_write_reg(TI_CCxxx0_ADDR,     0x01);  // Device address.
    cc_spi_write_reg(TI_CCxxx0_CHANNR,   0x00); // Channel number.
    cc_spi_write_reg(TI_CCxxx0_FSCTRL1,  0x07); // Freq synthesizer control.
    cc_spi_write_reg(TI_CCxxx0_FSCTRL0,  0x00); // Freq synthesizer control.
#if 0
    cc_spi_write_reg(TI_CCxxx0_FREQ2,    0x5D); // Freq control word, high byte
    cc_spi_write_reg(TI_CCxxx0_FREQ1,    0x93); // Freq control word, mid byte.
    cc_spi_write_reg(TI_CCxxx0_FREQ0,    0xB1); // Freq control word, low byte.
#endif
    cc_spi_write_reg(TI_CCxxx0_FREQ2,    0x5c); // Freq control word, high byte
    cc_spi_write_reg(TI_CCxxx0_FREQ1,    0x80); // Freq control word, mid byte.
    cc_spi_write_reg(TI_CCxxx0_FREQ0,    0x00); // Freq control word, low byte.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG4,  0x2D); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG3,  0x3B); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG2,  0x73); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG1,  0x22); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG0,  0xF8); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_DEVIATN,  0x00); // Modem dev (when FSK mod en)
    cc_spi_write_reg(TI_CCxxx0_MCSM1 ,   0x3F); //MainRadio Cntrl State Machine
    cc_spi_write_reg(TI_CCxxx0_MCSM0 ,   0x18); //MainRadio Cntrl State Machine
    cc_spi_write_reg(TI_CCxxx0_FOCCFG,   0x1D); // Freq Offset Compens. Config
    cc_spi_write_reg(TI_CCxxx0_BSCFG,    0x1C); //  Bit synchronization config.
    cc_spi_write_reg(TI_CCxxx0_AGCCTRL2, 0xC7); // AGC control.
    cc_spi_write_reg(TI_CCxxx0_AGCCTRL1, 0x00); // AGC control.
    cc_spi_write_reg(TI_CCxxx0_AGCCTRL0, 0xB2); // AGC control.
    cc_spi_write_reg(TI_CCxxx0_FREND1,   0xB6); // Front end RX configuration.
    cc_spi_write_reg(TI_CCxxx0_FREND0,   0x10); // Front end RX configuration.
    cc_spi_write_reg(TI_CCxxx0_FSCAL3,   0xEA); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSCAL2,   0x0A); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSCAL1,   0x00); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSCAL0,   0x11); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSTEST,   0x59); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_TEST2,    0x88); // Various test settings.
    cc_spi_write_reg(TI_CCxxx0_TEST1,    0x31); // Various test settings.
    cc_spi_write_reg(TI_CCxxx0_TEST0,    0x0B); // Various test settings.
#endif

#if 0
    // Write register settings
 cc_spi_write_reg(TI_CCxxx0_IOCFG2,   0x0B); // GDO2 output pin config.
 cc_spi_write_reg(TI_CCxxx0_IOCFG0,   0x06); // GDO0 output pin config.
 cc_spi_write_reg(TI_CCxxx0_PKTLEN,   0xFF); // Packet length.
 cc_spi_write_reg(TI_CCxxx0_PKTCTRL1, 0x05); // Packet automation control.
 cc_spi_write_reg(TI_CCxxx0_PKTCTRL0, 0x22); // Packet automation control.
 cc_spi_write_reg(TI_CCxxx0_ADDR,     0x01); // Device address.
 cc_spi_write_reg(TI_CCxxx0_CHANNR,   0x00); // Channel number.
 cc_spi_write_reg(TI_CCxxx0_FSCTRL1,  0x12); // Freq synthesizer control.
 cc_spi_write_reg(TI_CCxxx0_FSCTRL0,  0x00); // Freq synthesizer control.
 cc_spi_write_reg(TI_CCxxx0_FREQ2,    0x5c); // Freq control word, high byte
 cc_spi_write_reg(TI_CCxxx0_FREQ1,    0x80); // Freq control word, mid byte.
 cc_spi_write_reg(TI_CCxxx0_FREQ0,    0x00); // Freq control word, low byte.
 cc_spi_write_reg(TI_CCxxx0_MDMCFG4,  0x2D); // Modem configuration.
 cc_spi_write_reg(TI_CCxxx0_MDMCFG3,  0x3B); // Modem configuration.
 cc_spi_write_reg(TI_CCxxx0_MDMCFG2,  0xF3); // Modem configuration.
 cc_spi_write_reg(TI_CCxxx0_MDMCFG1,  0x22); // Modem configuration.
 cc_spi_write_reg(TI_CCxxx0_MDMCFG0,  0xF8); // Modem configuration.
 cc_spi_write_reg(TI_CCxxx0_DEVIATN,  0x00); // Modem dev (when FSK mod en)
 cc_spi_write_reg(TI_CCxxx0_MCSM1 ,   0x3F); // MainRadio Cntrl State Machine
 cc_spi_write_reg(TI_CCxxx0_MCSM0 ,   0x18); // MainRadio Cntrl State Machine
 cc_spi_write_reg(TI_CCxxx0_FOCCFG,   0x1D); // Freq Offset Compens. Config
 cc_spi_write_reg(TI_CCxxx0_BSCFG,    0x1C); // Bit synchronization config.
 cc_spi_write_reg(TI_CCxxx0_AGCCTRL2, 0xC7); // AGC control.
 cc_spi_write_reg(TI_CCxxx0_AGCCTRL1, 0x00); // AGC control.
 cc_spi_write_reg(TI_CCxxx0_AGCCTRL0, 0xB0); // AGC control.
 cc_spi_write_reg(TI_CCxxx0_FREND1,   0xB6); // Front end RX configuration.
 cc_spi_write_reg(TI_CCxxx0_FREND0,   0x10); // Front end RX configuration.
 cc_spi_write_reg(TI_CCxxx0_FSCAL3,   0xEA); // Frequency synthesizer cal.
 cc_spi_write_reg(TI_CCxxx0_FSCAL2,   0x0A); // Frequency synthesizer cal.
 cc_spi_write_reg(TI_CCxxx0_FSCAL1,   0x00); // Frequency synthesizer cal.
 cc_spi_write_reg(TI_CCxxx0_FSCAL0,   0x11); // Frequency synthesizer cal.
 cc_spi_write_reg(TI_CCxxx0_FSTEST,   0x59); // Frequency synthesizer cal.
 cc_spi_write_reg(TI_CCxxx0_TEST2,    0x88); // Various test settings.
 cc_spi_write_reg(TI_CCxxx0_TEST1,    0x31); // Various test settings.
 cc_spi_write_reg(TI_CCxxx0_TEST0,    0x0B); // Various test settings.
#endif

#if 1
    // Write register settings
    cc_spi_write_reg(TI_CCxxx0_IOCFG2,   0x0B);  // GDO2 output pin config.
 //cc_spi_write_reg(TI_CCxxx0_IOCFG2,   0x3A);  // GDO2 output pin config.
    cc_spi_write_reg(TI_CCxxx0_IOCFG0,   0x06);  // GDO0 output pin config.
    cc_spi_write_reg(TI_CCxxx0_PKTLEN,   0xFF);  // Packet length.
    cc_spi_write_reg(TI_CCxxx0_PKTCTRL1, 0x05);  // Packet automation control.
    cc_spi_write_reg(TI_CCxxx0_PKTCTRL0, 0x05);  // Packet automation control.
    cc_spi_write_reg(TI_CCxxx0_ADDR,     0x01);  // Device address.
    cc_spi_write_reg(TI_CCxxx0_CHANNR,   0x00); // Channel number.
    cc_spi_write_reg(TI_CCxxx0_FSCTRL1,  0x06); // Freq synthesizer control.
    cc_spi_write_reg(TI_CCxxx0_FSCTRL0,  0x00); // Freq synthesizer control.
    cc_spi_write_reg(TI_CCxxx0_FREQ2,    0x5c); // Freq control word, high byte
    cc_spi_write_reg(TI_CCxxx0_FREQ1,    0x80); // Freq control word, mid byte.
    cc_spi_write_reg(TI_CCxxx0_FREQ0,    0x00); // Freq control word, low byte.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG4,  0x78); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG3,  0x93); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG2,  0x03); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG1,  0x22); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_MDMCFG0,  0xF8); // Modem configuration.
    cc_spi_write_reg(TI_CCxxx0_DEVIATN,  0x44); // Modem dev (when FSK mod en)
    cc_spi_write_reg(TI_CCxxx0_MCSM1 ,   0x3F); //MainRadio Cntrl State Machine
    cc_spi_write_reg(TI_CCxxx0_MCSM0 ,   0x18); //MainRadio Cntrl State Machine
    cc_spi_write_reg(TI_CCxxx0_FOCCFG,   0x16); // Freq Offset Compens. Config
    cc_spi_write_reg(TI_CCxxx0_BSCFG,    0x6C); //  Bit synchronization config.
    cc_spi_write_reg(TI_CCxxx0_AGCCTRL2, 0x43); // AGC control.
    cc_spi_write_reg(TI_CCxxx0_AGCCTRL1, 0x40); // AGC control.
    cc_spi_write_reg(TI_CCxxx0_AGCCTRL0, 0x91); // AGC control.
    cc_spi_write_reg(TI_CCxxx0_FREND1,   0x56); // Front end RX configuration.
    cc_spi_write_reg(TI_CCxxx0_FREND0,   0x10); // Front end RX configuration.
    cc_spi_write_reg(TI_CCxxx0_FSCAL3,   0xA9); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSCAL2,   0x0A); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSCAL1,   0x00); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSCAL0,   0x11); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_FSTEST,   0x59); // Frequency synthesizer cal.
    cc_spi_write_reg(TI_CCxxx0_TEST2,    0x88); // Various test settings.
    cc_spi_write_reg(TI_CCxxx0_TEST1,    0x31); // Various test settings.
    cc_spi_write_reg(TI_CCxxx0_TEST0,    0x0B); // Various test settings.
#endif
}

// PATABLE (0 dBm output power)
//u8_t paTable[] = {0xFB};
u8_t paTable[] = {0xFF};
u8_t paTableLen = 1;

// 发送数据包
void cc_send_packet(u8_t *tx_buf, u8_t size)
{
 // 先进空闲,防止锁死
 cc_spi_strobe(TI_CCxxx0_SIDLE);
    cc_spi_write_burst_reg(TI_CCxxx0_TXFIFO, tx_buf, size); // Write TX data
    cc_wait(30);
    //cc_spi_write_reg(TI_CCxxx0_FREND0, 0x10); // POWER = 10dbm
    //cc_wait(30);
    cli();
    cc_spi_strobe(TI_CCxxx0_STX); // STX="0x35" enable TX.
    while ((PIND&CC2500_GDO0) == 0) ; // wait for GDO0 hi, sync TX'ed
    while ((PIND&CC2500_GDO0) != 0) ; // wait for GDO0 lo, end of pkt
    sei();
}

//
u8_t cc_receive_packet(u8_t *rx_buf, u8_t *length)
{
    u8_t status[2];
    u8_t pktlen;

    if ((cc_spi_read_status(TI_CCxxx0_RXBYTES) & TI_CCxxx0_NUM_RXBYTES)) {
        pktlen = cc_spi_read_reg(TI_CCxxx0_RXFIFO); // read length byte

        if (pktlen <= *length) { // if pktlen size <= rx_buf
            cc_spi_read_burst_reg(TI_CCxxx0_RXFIFO, rx_buf, pktlen); // Pull data
            *length = pktlen; // return the actual size
            cc_spi_read_burst_reg(TI_CCxxx0_RXFIFO, status, 2); // read appended status byte
            return (u8_t)(status[TI_CCxxx0_LQI_RX]&TI_CCxxx0_CRC_OK); // return CRC_OK bit
        } else {
            *length = pktlen;
            cc_spi_strobe(TI_CCxxx0_SFRX); // Flush RXFIFO
            return 0; // error
        }
    } else {
        return 0; // error
    }
}

// 接收中断函数
SIGNAL(SIG_INTERRUPT0)
{
 rx_pkt_2500.len = 32;
 rx_state_2500 = cc_receive_packet(rx_pkt_2500.buf, &(rx_pkt_2500.len));
 if (rx_state_2500 != 0)
  rx_flag_2500 = 1;
 cc_spi_strobe(TI_CCxxx0_SRX); // 返回接收
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客