头文件: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;
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 = 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); // 返回接收
}
用户951650 2011-9-8 09:56
用户1593803 2011-7-7 14:55
用户1275742 2009-11-19 08:55
朱玉龙 2009-11-18 21:27