首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
系统相关
> 详细
linux 驱动cc1101
时间:
2015-04-07 11:43:47
阅读:
331
评论:
0
收藏:
0
[点我收藏+]
标签:
cc1101.h:
[cpp]
view plain
copy
print
?
#ifndef _CC1101_H
#define _CC1101_H
#define INT8U unsigned char
#define INT16U unsigned int
#define WRITE_BURST 0x40 //连续写入
#define READ_SINGLE 0x80 //读
#define READ_BURST 0xC0 //连续读
#define BYTES_IN_RXFIFO 0x7F //接收缓冲区的有效字节数
#define CRC_OK 0x80 //CRC校验通过位标志
#define CCxxx0_IOCFG2 0x00 // GDO2 output pin configuration
#define CCxxx0_IOCFG1 0x01 // GDO1 output pin configuration
#define CCxxx0_IOCFG0 0x02 // GDO0 output pin configuration
#define CCxxx0_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
#define CCxxx0_SYNC1 0x04 // Sync word, high INT8U
#define CCxxx0_SYNC0 0x05 // Sync word, low INT8U
#define CCxxx0_PKTLEN 0x06 // Packet length
#define CCxxx0_PKTCTRL1 0x07 // Packet automation control
#define CCxxx0_PKTCTRL0 0x08 // Packet automation control
#define CCxxx0_ADDR 0x09 // Device address
#define CCxxx0_CHANNR 0x0A // Channel number
#define CCxxx0_FSCTRL1 0x0B // Frequency synthesizer control
#define CCxxx0_FSCTRL0 0x0C // Frequency synthesizer control
#define CCxxx0_FREQ2 0x0D // Frequency control word, high INT8U
#define CCxxx0_FREQ1 0x0E // Frequency control word, middle INT8U
#define CCxxx0_FREQ0 0x0F // Frequency control word, low INT8U
#define CCxxx0_MDMCFG4 0x10 // Modem configuration
#define CCxxx0_MDMCFG3 0x11 // Modem configuration
#define CCxxx0_MDMCFG2 0x12 // Modem configuration
#define CCxxx0_MDMCFG1 0x13 // Modem configuration
#define CCxxx0_MDMCFG0 0x14 // Modem configuration
#define CCxxx0_DEVIATN 0x15 // Modem deviation setting
#define CCxxx0_MCSM2 0x16 // Main Radio Control State Machine configuration
#define CCxxx0_MCSM1 0x17 // Main Radio Control State Machine configuration
#define CCxxx0_MCSM0 0x18 // Main Radio Control State Machine configuration
#define CCxxx0_FOCCFG 0x19 // Frequency Offset Compensation configuration
#define CCxxx0_BSCFG 0x1A // Bit Synchronization configuration
#define CCxxx0_AGCCTRL2 0x1B // AGC control
#define CCxxx0_AGCCTRL1 0x1C // AGC control
#define CCxxx0_AGCCTRL0 0x1D // AGC control
#define CCxxx0_WOREVT1 0x1E // High INT8U Event 0 timeout
#define CCxxx0_WOREVT0 0x1F // Low INT8U Event 0 timeout
#define CCxxx0_WORCTRL 0x20 // Wake On Radio control
#define CCxxx0_FREND1 0x21 // Front end RX configuration
#define CCxxx0_FREND0 0x22 // Front end TX configuration
#define CCxxx0_FSCAL3 0x23 // Frequency synthesizer calibration
#define CCxxx0_FSCAL2 0x24 // Frequency synthesizer calibration
#define CCxxx0_FSCAL1 0x25 // Frequency synthesizer calibration
#define CCxxx0_FSCAL0 0x26 // Frequency synthesizer calibration
#define CCxxx0_RCCTRL1 0x27 // RC oscillator configuration
#define CCxxx0_RCCTRL0 0x28 // RC oscillator configuration
#define CCxxx0_FSTEST 0x29 // Frequency synthesizer calibration control
#define CCxxx0_PTEST 0x2A // Production test
#define CCxxx0_AGCTEST 0x2B // AGC test
#define CCxxx0_TEST2 0x2C // Various test settings
#define CCxxx0_TEST1 0x2D // Various test settings
#define CCxxx0_TEST0 0x2E // Various test settings
// Strobe commands
#define CCxxx0_SRES 0x30 // Reset chip.
#define CCxxx0_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
// If in RX/TX: Go to a wait state where only the synthesizer is
// running (for quick RX / TX turnaround).
#define CCxxx0_SXOFF 0x32 // Turn off crystal oscillator.
#define CCxxx0_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
// (enables quick start).
#define CCxxx0_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
// MCSM0.FS_AUTOCAL=1.
#define CCxxx0_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
// Only go to TX if channel is clear.
#define CCxxx0_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
// Wake-On-Radio mode if applicable.
#define CCxxx0_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
#define CCxxx0_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
#define CCxxx0_SPWD 0x39 // Enter power down mode when CSn goes high.
#define CCxxx0_SFRX 0x3A // Flush the RX FIFO buffer.
#define CCxxx0_SFTX 0x3B // Flush the TX FIFO buffer.
#define CCxxx0_SWORRST 0x3C // Reset real time clock.
#define CCxxx0_SNOP 0x3D // No operation. May be used to pad strobe commands to two
// INT8Us for simpler software.
#define CCxxx0_PARTNUM 0x30
#define CCxxx0_VERSION 0x31
#define CCxxx0_FREQEST 0x32
#define CCxxx0_LQI 0x33
#define CCxxx0_RSSI 0x34
#define CCxxx0_MARCSTATE 0x35
#define CCxxx0_WORTIME1 0x36
#define CCxxx0_WORTIME0 0x37
#define CCxxx0_PKTSTATUS 0x38
#define CCxxx0_VCO_VC_DAC 0x39
#define CCxxx0_TXBYTES 0x3A
#define CCxxx0_RXBYTES 0x3B
#define CCxxx0_PATABLE 0x3E
#define CCxxx0_TXFIFO 0x3F
#define CCxxx0_RXFIFO 0x3F
// RF_SETTINGS is a data structure which contains all relevant CCxxx0 registers
typedef
struct {
INT8U iocfg0;
// GDO0 Output Pin Configuration
INT8U fifothr;
// RX FIFO and TX FIFO Thresholds
INT8U pktctrl0;
// Packet Automation Control
INT8U fsctrl1;
// Frequency Synthesizer Control
INT8U freq2;
// Frequency Control Word, High Byte
INT8U freq1;
// Frequency Control Word, Middle Byte
INT8U freq0;
// Frequency Control Word, Low Byte
INT8U mdmcfg4;
// Modem Configuration
INT8U mdmcfg3;
// Modem Configuration
INT8U mdmcfg2;
// Modem Configuration
INT8U deviatn;
// Modem Deviation Setting
INT8U mcsm0;
// Main Radio Control State Machine Configuration
INT8U foccfg;
// Frequency Offset Compensation Configuration
INT8U worctrl;
// Wake On Radio Control
INT8U fscal3;
// Frequency Synthesizer Calibration
INT8U fscal2;
// Frequency Synthesizer Calibration
INT8U fscal1;
// Frequency Synthesizer Calibration
INT8U fscal0;
// Frequency Synthesizer Calibration
INT8U test2;
// Various Test Settings
INT8U test1;
// Various Test Settings
INT8U test0;
// Various Test Settings
} RF_SETTINGS;
#endif
cc1101.c
[cpp]
view plain
copy
print
?
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_*_user */
#include "cc1101.h"
int
nop_tmp;
typedef
struct
cc1101_spi_pin_t
{
unsigned
long
spi_SCK;
/* GPF4 = SCK 输出 */
unsigned
long
spi_MOSI;
/* GPF3 = MOSI 输出 */
unsigned
long
spi_GDO2;
/* GPG6 = GD02 输出 */
unsigned
long
spi_MISO;
/* GPG5 = MISO 输入 */
unsigned
long
spi_CSN;
/* GPG11 = CSN 输出 */
unsigned
long
spi_GDO0;
/* GPG7 = GD01 输入类型 */
}cc1101_spi_pin;
typedef
struct
cc1101_spi_pintype_t
{
unsigned
long
spi_SCK;
/* GPF4 = SCK 输出 */
unsigned
long
spi_MOSI;
/* GPF3 = MOSI 输出 */
unsigned
long
spi_GDO2;
/* GPG6 = GD02 输出 */
unsigned
long
spi_MISO;
/* GPG5 = MISO 输入 */
unsigned
long
spi_CSN;
/* GPG11 = CSN 输出 */
unsigned
long
spi_GDO0;
/* GPG7 = GD01 下降沿中断类型 */
}cc1101_spi_pintype;
static
cc1101_spi_pin cc1101_pin = {
S3C2410_GPF4,
S3C2410_GPF3,
S3C2410_GPG6,
S3C2410_GPG5,
S3C2410_GPG11,
S3C2410_GPG7,
};
static
cc1101_spi_pintype cc1101_pintype = {
S3C2410_GPF4_OUTP,
S3C2410_GPF3_OUTP,
S3C2410_GPG6_OUTP,
S3C2410_GPG5_INP,
S3C2410_GPG11_OUTP,
S3C2410_GPG7_EINT15,
};
#define MISO s3c2410_gpio_getpin(cc1101_pin.spi_MISO)
#define GDO0 s3c2410_gpio_getpin(cc1101_pin.spi_GDO0)
#define MOSI_H s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 1)
#define MOSI_L s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 0)
#define CSN_H s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 1)
#define CSN_L s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 0)
#define SCK_H s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 1)
#define SCK_L s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 0)
#define GDO2_H s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 1)
#define GDO2_L s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 0)
void
soc_init(
void
)
{
s3c2410_gpio_cfgpin(cc1101_pin.spi_SCK, cc1101_pintype.spi_SCK);
s3c2410_gpio_cfgpin(cc1101_pin.spi_MOSI, cc1101_pintype.spi_MOSI);
s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO2, cc1101_pintype.spi_GDO2);
s3c2410_gpio_cfgpin(cc1101_pin.spi_MISO, cc1101_pintype.spi_MISO);
s3c2410_gpio_cfgpin(cc1101_pin.spi_CSN, cc1101_pintype.spi_CSN);
s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO0, cc1101_pintype.spi_GDO0);
printk(
"cc1101 set pin ok!"
);
}
static
void
cc1101_delay(unsigned
int
s)
{
unsigned
int
i;
for
(i = 0; i < s; i++);
for
(i = 0; i < s; i++);
}
void
halWait(INT16U timeout)
{
int
i;
do
{
for
(i = 0; i < 150; i++)
nop_tmp++;
}
while
(--timeout);
}
void
SpiInit(
void
)
{
CSN_L;
SCK_L;
CSN_H;
}
/*****************************************************************************************/
//鍑芥暟鍚嶏細CpuInit()
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍒濆鍖栫▼搴?
/*****************************************************************************************/
void
CpuInit(
void
)
{
soc_init();
SpiInit();
cc1101_delay(1500000);
}
//*****************************************************************************************
//鍑芥暟鍚嶏細SpisendByte(INT8U dat)
//杈撳叆锛氬彂閫佺殑鏁版嵁
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍙戦€佷竴涓瓧鑺?
//*****************************************************************************************
INT8U SpiTxRxByte(INT8U dat)
{
INT8U i,temp;
temp = 0;
SCK_L;
for
(i=0; i<8; i++)
{
if
(dat & 0x80)
{
MOSI_H;
}
else
MOSI_L;
dat <<= 1;
SCK_H;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
temp <<= 1;
if
(MISO)temp++;
SCK_L;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
}
return
temp;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void RESET_CC1100(void)
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛氬浣岰C1100
//*****************************************************************************************
void
RESET_CC1100(
void
)
{
CSN_L;
while
(MISO);
SpiTxRxByte(CCxxx0_SRES);
//鍐欏叆澶嶄綅鍛戒护
while
(MISO);
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void POWER_UP_RESET_CC1100(void)
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛氫笂鐢靛浣岰C1100
//*****************************************************************************************
void
POWER_UP_RESET_CC1100(
void
)
{
CSN_H;
halWait(10);
CSN_L;
halWait(10);
CSN_H;
halWait(410);
RESET_CC1100();
//澶嶄綅CC1100
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiWriteReg(INT8U addr, INT8U value)
//杈撳叆锛氬湴鍧€鍜岄厤缃瓧
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍐欏瘎瀛樺櫒
//*****************************************************************************************
void
halSpiWriteReg(INT8U addr, INT8U value)
{
CSN_L;
while
(MISO);
SpiTxRxByte(addr);
//鍐欏湴鍧€
SpiTxRxByte(value);
//鍐欏叆閰嶇疆
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
//杈撳叆锛氬湴鍧€锛屽啓鍏ョ紦鍐插尯锛屽啓鍏ヤ釜鏁?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
//*****************************************************************************************
void
halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
{
INT8U i, temp;
temp = addr | WRITE_BURST;
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
for
(i = 0; i < count; i++)
{
SpiTxRxByte(buffer[i]);
}
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiStrobe(INT8U strobe)
//杈撳叆锛氬懡浠?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍐欏懡浠?
//*****************************************************************************************
void
halSpiStrobe(INT8U strobe)
{
CSN_L;
while
(MISO);
SpiTxRxByte(strobe);
//鍐欏叆鍛戒护
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
//杈撳叆锛氬湴鍧€
//杈撳嚭锛氳瀵勫瓨鍣ㄧ殑閰嶇疆瀛?
//鍔熻兘鎻忚堪锛歋PI璇诲瘎瀛樺櫒
//*****************************************************************************************
INT8U halSpiReadReg(INT8U addr)
{
INT8U temp, value;
temp = addr|READ_SINGLE;
//璇诲瘎瀛樺櫒鍛戒护
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
value = SpiTxRxByte(0);
CSN_H;
return
value;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
//杈撳叆锛氬湴鍧€锛岃鍑烘暟鎹悗鏆傚瓨鐨勭紦鍐插尯锛岃鍑洪厤缃釜鏁?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
//*****************************************************************************************
void
halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
{
INT8U i,temp;
temp = addr | READ_BURST;
//鍐欏叆瑕佽鐨勯厤缃瘎瀛樺櫒鍦板潃鍜岃鍛戒护
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
for
(i = 0; i < count; i++)
{
buffer[i] = SpiTxRxByte(0);
}
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
//杈撳叆锛氬湴鍧€
//杈撳嚭锛氳鐘舵€佸瘎瀛樺櫒褰撳墠鍊?
//鍔熻兘鎻忚堪锛歋PI璇荤姸鎬佸瘎瀛樺櫒
//*****************************************************************************************
INT8U halSpiReadStatus(INT8U addr)
{
INT8U value,temp;
temp = addr | READ_BURST;
//鍐欏叆瑕佽鐨勭姸鎬佸瘎瀛樺櫒鐨勫湴鍧€鍚屾椂鍐欏叆璇诲懡浠?
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
value = SpiTxRxByte(0);
CSN_H;
return
value;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halRfWriteRfSettings(RF_SETTINGS *pRfSettings)
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛氶厤缃瓹C1100鐨勫瘎瀛樺櫒
//*****************************************************************************************
void
halRfWriteRfSettings(
void
)
{
//*******************************此rfSettings配置来自Smart RF***********************************//
//*******************************Low data rate----2.4kbaud**************************************//
//*******************************Carrier frequency-----433.99MHz********************************//
RF_SETTINGS rfSettings = {
0x06,
// IOCFG0 GDO0 Output Pin Configuration
0x47,
// FIFOTHR RX FIFO and TX FIFO Thresholds
0x05,
// PKTCTRL0 Packet Automation Control
0x06,
// FSCTRL1 Frequency Synthesizer Control
0x10,
// FREQ2 Frequency Control Word, High Byte
0xB1,
// FREQ1 Frequency Control Word, Middle Byte
0x3B,
// FREQ0 Frequency Control Word, Low Byte
0xF6,
// MDMCFG4 Modem Configuration
0x83,
// MDMCFG3 Modem Configuration
0x13,
// MDMCFG2 Modem Configuration
0x15,
// DEVIATN Modem Deviation Setting
0x18,
// MCSM0 Main Radio Control State Machine Configuration
0x16,
// FOCCFG Frequency Offset Compensation Configuration
0xFB,
// WORCTRL Wake On Radio Control
0xE9,
// FSCAL3 Frequency Synthesizer Calibration
0x2A,
// FSCAL2 Frequency Synthesizer Calibration
0x00,
// FSCAL1 Frequency Synthesizer Calibration
0x1F,
// FSCAL0 Frequency Synthesizer Calibration
0x81,
// TEST2 Various Test Settings
0x35,
// TEST1 Various Test Settings
0x09,
// TEST0 Various Test Settings
};
halSpiWriteReg(CCxxx0_IOCFG0, rfSettings.iocfg0);
halSpiWriteReg(CCxxx0_FIFOTHR, rfSettings.fifothr);
halSpiWriteReg(CCxxx0_PKTCTRL0, rfSettings.pktctrl0);
halSpiWriteReg(CCxxx0_FSCTRL1, rfSettings.fsctrl1);
halSpiWriteReg(CCxxx0_FREQ2, rfSettings.freq2);
halSpiWriteReg(CCxxx0_FREQ1, rfSettings.freq1);
halSpiWriteReg(CCxxx0_FREQ0, rfSettings.freq0);
halSpiWriteReg(CCxxx0_MDMCFG4, rfSettings.mdmcfg4);
halSpiWriteReg(CCxxx0_MDMCFG3, rfSettings.mdmcfg3);
halSpiWriteReg(CCxxx0_MDMCFG2, rfSettings.mdmcfg2);
halSpiWriteReg(CCxxx0_DEVIATN, rfSettings.deviatn);
halSpiWriteReg(CCxxx0_MCSM0, rfSettings.mcsm0);
halSpiWriteReg(CCxxx0_FOCCFG, rfSettings.foccfg);
halSpiWriteReg(CCxxx0_WORCTRL, rfSettings.worctrl);
halSpiWriteReg(CCxxx0_FSCAL3, rfSettings.fscal3);
halSpiWriteReg(CCxxx0_FSCAL2, rfSettings.fscal2);
halSpiWriteReg(CCxxx0_FSCAL1, rfSettings.fscal1);
halSpiWriteReg(CCxxx0_FSCAL0, rfSettings.fscal0);
halSpiWriteReg(CCxxx0_TEST2, rfSettings.test2);
halSpiWriteReg(CCxxx0_TEST1, rfSettings.test1);
halSpiWriteReg(CCxxx0_TEST0, rfSettings.test0);
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halRfSendPacket(INT8U *txBuffer, INT8U size)
//杈撳叆锛氬彂閫佺殑缂撳啿鍖猴紝鍙戦€佹暟鎹釜鏁?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛欳C1100鍙戦€佷竴缁勬暟鎹?
//*****************************************************************************************
void
halRfSendPacket(INT8U *txBuffer, INT8U size)
{
halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_STX);
//杩涘叆鍙戦€佹ā寮忓彂閫佹暟鎹?
halSpiWriteReg(CCxxx0_TXFIFO, size);
halSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size);
//鍐欏叆瑕佸彂閫佺殑鏁版嵁
// Wait for GDO0 to be set -> sync transmitted
while
(!GDO0);
// Wait for GDO0 to be cleared -> end of packet
while
(GDO0);
halSpiStrobe(CCxxx0_SFTX);
halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_SRX);
}
//************************************************************************************************//
//********************************* 鏃犱腑鏂帴鏀跺嚱鏁? ************************************//
//***********************************************************************************************//
INT8U halRfReceivePacket(INT8U *rxBuffer, INT8U *length)
{
INT8U status[2];
INT8U packetLength;
INT8U i=(*length)*4;
// 鍏蜂綋澶氬皯瑕佹牴鎹甦atarate鍜宭ength鏉ュ喅瀹?
halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_SRX);
//杩涘叆鎺ユ敹鐘舵€?
cc1101_delay(20);
while
(GDO0)
{
cc1101_delay(20);
--i;
if
(i<1)
return
0;
}
if
((halSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO))
//濡傛灉鎺ョ殑瀛楄妭鏁颁笉涓?
{
packetLength = halSpiReadReg(CCxxx0_RXFIFO);
//璇诲嚭绗竴涓瓧鑺傦紝姝ゅ瓧鑺備负璇ュ抚鏁版嵁闀垮害
if
(packetLength <= *length)
//濡傛灉鎵€瑕佺殑鏈夋晥鏁版嵁闀垮害灏忎簬绛変簬鎺ユ敹鍒扮殑鏁版嵁鍖呯殑闀垮害
{
halSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength);
//璇诲嚭鎵€鏈夋帴鏀跺埌鐨勬暟鎹?
*length = packetLength;
//鎶婃帴鏀舵暟鎹暱搴︾殑淇敼涓哄綋鍓嶆暟鎹殑闀垮害
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
halSpiReadBurstReg(CCxxx0_RXFIFO, status, 2);
//璇诲嚭CRC鏍¢獙浣?
halSpiStrobe(CCxxx0_SFRX);
//娓呮礂鎺ユ敹缂撳啿鍖?
return
(status[1] & CRC_OK);
//濡傛灉鏍¢獙鎴愬姛杩斿洖鎺ユ敹鎴愬姛
}
else
{
*length = packetLength;
halSpiStrobe(CCxxx0_SFRX);
//娓呮礂鎺ユ敹缂撳啿鍖?
return
0;
}
}
else
return
0;
}
static
int
Init_CC1100(
void
)
{
INT8U PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};
CpuInit();
POWER_UP_RESET_CC1100();
halRfWriteRfSettings();
halSpiWriteBurstReg(CCxxx0_PATABLE, PaTabel, 8);
return
0;
}
/****************************************************************************************/
#define CC1101_BUFLEN 16
static
dev_t cc1101_dev_no = 0;
static
volatile
int
rcv_flag;
/* cc1101设备 */
typedef
struct
tag_cc1101_dev_t
{
struct
cdev cdev;
unsigned
char
cc1101_buf[CC1101_BUFLEN];
wait_queue_head_t read_wait;
}cc1101_dev_t;
static
cc1101_dev_t cc1101_dev;
struct
rcv_irq_desc {
int
irq;
int
pin;
int
pin_setting;
char
*name;
};
static
irqreturn_t cc1101_rcv_interrupt(
int
irq,
void
*dev_id)
{
INT8U count = CC1101_BUFLEN;
int
ret;
printk(
"cc1101 handle interrupt!\n"
);
ret = halRfReceivePacket(cc1101_dev.cc1101_buf, &count);
if
(0 != ret)
{
/*
printk("cc1101 receiving .... start\n");
printk("cc1101 receiving .... end\n");
printk("cc1101 receiving %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
*/
rcv_flag = 1;
wake_up_interruptible(&cc1101_dev.read_wait);
}
return
IRQ_RETVAL(IRQ_HANDLED);
}
static
struct
rcv_irq_desc cc1101_rcv_irq = {
IRQ_EINT15,
S3C2410_GPG7,
S3C2410_GPG7_EINT15,
"spi_GDO0"
};
/*文件打开函数*/
int
cc1101_open(
struct
inode *inode,
struct
file *filp)
{
int
ret;
ret = request_irq(cc1101_rcv_irq.irq, cc1101_rcv_interrupt, IRQ_TYPE_EDGE_FALLING,
cc1101_rcv_irq.name, (
void
*)&cc1101_rcv_irq);
if
(ret)
{
printk(
"request_irq error!\n"
);
return
-EBUSY;
}
return
0;
}
/*写函数*/
static
ssize_t cc1101_write(
struct
file *filp,
const
char
__user *buf,
size_t
size, loff_t *ppos)
{
unsigned
int
count = size;
int
ret = 0;
/*分析和获取有效的写长度*/
if
(CC1101_BUFLEN != size)
{
printk(
"cc1101 write wrong len:%d\n"
, size);
return
-ENOMEM;
}
/*用户空间->内核空间*/
if
(copy_from_user(cc1101_dev.cc1101_buf, buf, count))
ret = - EFAULT;
else
{
ret = count;
//printk("kernel-space: cc1101 written %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
}
/* CC1101硬件发送 */
//printk("kernel-space: cc1101 sending .... start\n");
halRfSendPacket(cc1101_dev.cc1101_buf, count);
//printk("kernel-space: cc1101 sending .... end\n");
return
ret;
}
/* 读函数 */
static
ssize_t cc1101_waitqueue_read(
struct
file *filp,
char
__user *buf,
size_t
size, loff_t *ppos)
{
unsigned
int
count = size;
int
ret = 0;
DECLARE_WAITQUEUE(wait, current);
if
(CC1101_BUFLEN != count)
{
printk(
"kernel-space: cc1101 read wrong len:%d\n"
, count);
return
-ENOMEM;
}
add_wait_queue(&cc1101_dev.read_wait, &wait);
if
(0 == rcv_flag)
{
if
(filp->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
goto
out;
}
__set_current_state(TASK_INTERRUPTIBLE);
schedule();
if
(signal_pending(current))
{
ret = - ERESTARTSYS;
goto
out;
}
}
/* 内核空间->用户空间 */
copy_to_user(buf, cc1101_dev.cc1101_buf, count);
ret = count;
out:
remove_wait_queue(&cc1101_dev.read_wait, &wait);
set_current_state(TASK_RUNNING);
rcv_flag = 0;
return
ret;
}
/* poll函数 */
static
unsigned
int
cc1101_poll(
struct
file *filp, poll_table *wait)
{
unsigned
int
mask = 0;
poll_wait(filp, &cc1101_dev.read_wait, wait);
if
(1 == rcv_flag)
{
mask |= POLLIN | POLLRDNORM;
printk(
"kernel-space: cc1101_poll rcv_flag = 1!\n"
);
}
return
mask;
}
static
int
cc1101_close(
struct
inode *inode,
struct
file *file)
{
free_irq(cc1101_rcv_irq.irq, (
void
*)&cc1101_rcv_irq);
printk(
"kernel-space: cc1101_close!\n"
);
return
0;
}
struct
file_operations cc1101_fops =
{
.owner = THIS_MODULE,
.open = cc1101_open,
.release = cc1101_close,
.write = cc1101_write,
.read = cc1101_waitqueue_read,
.poll = cc1101_poll,
};
/*初始化并注册cdev*/
static
int
cc1101_setup_cdev(
void
)
{
int
err;
cdev_init(&cc1101_dev.cdev, &cc1101_fops);
cc1101_dev.cdev.owner = THIS_MODULE;
cc1101_dev.cdev.ops = &cc1101_fops;
err = cdev_add(&cc1101_dev.cdev, cc1101_dev_no, 1);
if
(err)
printk(
"cc1101 cc1101_setup_cdev error!"
);
return
err;
}
static
int
__init cc1101_init(
void
)
{
int
ret = 0;
ret = Init_CC1100();
if
(0 != ret)
goto
init_fail;
ret = alloc_chrdev_region(&cc1101_dev_no, 0, 1,
"cc1101"
);
if
(0 < ret)
goto
init_fail;
init_waitqueue_head(&cc1101_dev.read_wait);
ret = cc1101_setup_cdev();
if
(0 != ret)
{
unregister_chrdev_region(cc1101_dev_no, 1);
goto
init_fail;
}
printk(
"cc1101 init success!\n"
);
return
0;
init_fail:
printk(
"cc1101 init failed!\n"
);
return
ret;
}
static
void
__exit cc1101_exit(
void
)
{
unregister_chrdev_region(cc1101_dev_no, 1);
cdev_del(&cc1101_dev.cdev);
printk(
"cc1101 exit success!\n"
);
}
module_init(cc1101_init);
module_exit(cc1101_exit);
MODULE_LICENSE(
"GPL"
);
MODULE_AUTHOR(
"forsakening-hdu"
);
MODULE_DESCRIPTION(
"cc1101 control for EmbedSky TQ2440 Board"
);
cc1101.c
[cpp]
view plain
copy
print
?
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_*_user */
#include "cc1101.h"
int
nop_tmp;
typedef
struct
cc1101_spi_pin_t
{
unsigned
long
spi_SCK;
/* GPF4 = SCK 输出 */
unsigned
long
spi_MOSI;
/* GPF3 = MOSI 输出 */
unsigned
long
spi_GDO2;
/* GPG6 = GD02 输出 */
unsigned
long
spi_MISO;
/* GPG5 = MISO 输入 */
unsigned
long
spi_CSN;
/* GPG11 = CSN 输出 */
unsigned
long
spi_GDO0;
/* GPG7 = GD01 输入类型 */
}cc1101_spi_pin;
typedef
struct
cc1101_spi_pintype_t
{
unsigned
long
spi_SCK;
/* GPF4 = SCK 输出 */
unsigned
long
spi_MOSI;
/* GPF3 = MOSI 输出 */
unsigned
long
spi_GDO2;
/* GPG6 = GD02 输出 */
unsigned
long
spi_MISO;
/* GPG5 = MISO 输入 */
unsigned
long
spi_CSN;
/* GPG11 = CSN 输出 */
unsigned
long
spi_GDO0;
/* GPG7 = GD01 下降沿中断类型 */
}cc1101_spi_pintype;
static
cc1101_spi_pin cc1101_pin = {
S3C2410_GPF4,
S3C2410_GPF3,
S3C2410_GPG6,
S3C2410_GPG5,
S3C2410_GPG11,
S3C2410_GPG7,
};
static
cc1101_spi_pintype cc1101_pintype = {
S3C2410_GPF4_OUTP,
S3C2410_GPF3_OUTP,
S3C2410_GPG6_OUTP,
S3C2410_GPG5_INP,
S3C2410_GPG11_OUTP,
S3C2410_GPG7_EINT15,
};
#define MISO s3c2410_gpio_getpin(cc1101_pin.spi_MISO)
#define GDO0 s3c2410_gpio_getpin(cc1101_pin.spi_GDO0)
#define MOSI_H s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 1)
#define MOSI_L s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 0)
#define CSN_H s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 1)
#define CSN_L s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 0)
#define SCK_H s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 1)
#define SCK_L s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 0)
#define GDO2_H s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 1)
#define GDO2_L s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 0)
void
soc_init(
void
)
{
s3c2410_gpio_cfgpin(cc1101_pin.spi_SCK, cc1101_pintype.spi_SCK);
s3c2410_gpio_cfgpin(cc1101_pin.spi_MOSI, cc1101_pintype.spi_MOSI);
s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO2, cc1101_pintype.spi_GDO2);
s3c2410_gpio_cfgpin(cc1101_pin.spi_MISO, cc1101_pintype.spi_MISO);
s3c2410_gpio_cfgpin(cc1101_pin.spi_CSN, cc1101_pintype.spi_CSN);
s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO0, cc1101_pintype.spi_GDO0);
printk(
"cc1101 set pin ok!"
);
}
static
void
cc1101_delay(unsigned
int
s)
{
unsigned
int
i;
for
(i = 0; i < s; i++);
for
(i = 0; i < s; i++);
}
void
halWait(INT16U timeout)
{
int
i;
do
{
for
(i = 0; i < 150; i++)
nop_tmp++;
}
while
(--timeout);
}
void
SpiInit(
void
)
{
CSN_L;
SCK_L;
CSN_H;
}
/*****************************************************************************************/
//鍑芥暟鍚嶏細CpuInit()
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍒濆鍖栫▼搴?
/*****************************************************************************************/
void
CpuInit(
void
)
{
soc_init();
SpiInit();
cc1101_delay(1500000);
}
//*****************************************************************************************
//鍑芥暟鍚嶏細SpisendByte(INT8U dat)
//杈撳叆锛氬彂閫佺殑鏁版嵁
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍙戦€佷竴涓瓧鑺?
//*****************************************************************************************
INT8U SpiTxRxByte(INT8U dat)
{
INT8U i,temp;
temp = 0;
SCK_L;
for
(i=0; i<8; i++)
{
if
(dat & 0x80)
{
MOSI_H;
}
else
MOSI_L;
dat <<= 1;
SCK_H;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
temp <<= 1;
if
(MISO)temp++;
SCK_L;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
nop_tmp++;
}
return
temp;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void RESET_CC1100(void)
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛氬浣岰C1100
//*****************************************************************************************
void
RESET_CC1100(
void
)
{
CSN_L;
while
(MISO);
SpiTxRxByte(CCxxx0_SRES);
//鍐欏叆澶嶄綅鍛戒护
while
(MISO);
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void POWER_UP_RESET_CC1100(void)
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛氫笂鐢靛浣岰C1100
//*****************************************************************************************
void
POWER_UP_RESET_CC1100(
void
)
{
CSN_H;
halWait(10);
CSN_L;
halWait(10);
CSN_H;
halWait(410);
RESET_CC1100();
//澶嶄綅CC1100
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiWriteReg(INT8U addr, INT8U value)
//杈撳叆锛氬湴鍧€鍜岄厤缃瓧
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍐欏瘎瀛樺櫒
//*****************************************************************************************
void
halSpiWriteReg(INT8U addr, INT8U value)
{
CSN_L;
while
(MISO);
SpiTxRxByte(addr);
//鍐欏湴鍧€
SpiTxRxByte(value);
//鍐欏叆閰嶇疆
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
//杈撳叆锛氬湴鍧€锛屽啓鍏ョ紦鍐插尯锛屽啓鍏ヤ釜鏁?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
//*****************************************************************************************
void
halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
{
INT8U i, temp;
temp = addr | WRITE_BURST;
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
for
(i = 0; i < count; i++)
{
SpiTxRxByte(buffer[i]);
}
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiStrobe(INT8U strobe)
//杈撳叆锛氬懡浠?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI鍐欏懡浠?
//*****************************************************************************************
void
halSpiStrobe(INT8U strobe)
{
CSN_L;
while
(MISO);
SpiTxRxByte(strobe);
//鍐欏叆鍛戒护
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
//杈撳叆锛氬湴鍧€
//杈撳嚭锛氳瀵勫瓨鍣ㄧ殑閰嶇疆瀛?
//鍔熻兘鎻忚堪锛歋PI璇诲瘎瀛樺櫒
//*****************************************************************************************
INT8U halSpiReadReg(INT8U addr)
{
INT8U temp, value;
temp = addr|READ_SINGLE;
//璇诲瘎瀛樺櫒鍛戒护
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
value = SpiTxRxByte(0);
CSN_H;
return
value;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
//杈撳叆锛氬湴鍧€锛岃鍑烘暟鎹悗鏆傚瓨鐨勭紦鍐插尯锛岃鍑洪厤缃釜鏁?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
//*****************************************************************************************
void
halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
{
INT8U i,temp;
temp = addr | READ_BURST;
//鍐欏叆瑕佽鐨勯厤缃瘎瀛樺櫒鍦板潃鍜岃鍛戒护
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
for
(i = 0; i < count; i++)
{
buffer[i] = SpiTxRxByte(0);
}
CSN_H;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
//杈撳叆锛氬湴鍧€
//杈撳嚭锛氳鐘舵€佸瘎瀛樺櫒褰撳墠鍊?
//鍔熻兘鎻忚堪锛歋PI璇荤姸鎬佸瘎瀛樺櫒
//*****************************************************************************************
INT8U halSpiReadStatus(INT8U addr)
{
INT8U value,temp;
temp = addr | READ_BURST;
//鍐欏叆瑕佽鐨勭姸鎬佸瘎瀛樺櫒鐨勫湴鍧€鍚屾椂鍐欏叆璇诲懡浠?
CSN_L;
while
(MISO);
SpiTxRxByte(temp);
value = SpiTxRxByte(0);
CSN_H;
return
value;
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halRfWriteRfSettings(RF_SETTINGS *pRfSettings)
//杈撳叆锛氭棤
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛氶厤缃瓹C1100鐨勫瘎瀛樺櫒
//*****************************************************************************************
void
halRfWriteRfSettings(
void
)
{
//*******************************此rfSettings配置来自Smart RF***********************************//
//*******************************Low data rate----2.4kbaud**************************************//
//*******************************Carrier frequency-----433.99MHz********************************//
RF_SETTINGS rfSettings = {
0x06,
// IOCFG0 GDO0 Output Pin Configuration
0x47,
// FIFOTHR RX FIFO and TX FIFO Thresholds
0x05,
// PKTCTRL0 Packet Automation Control
0x06,
// FSCTRL1 Frequency Synthesizer Control
0x10,
// FREQ2 Frequency Control Word, High Byte
0xB1,
// FREQ1 Frequency Control Word, Middle Byte
0x3B,
// FREQ0 Frequency Control Word, Low Byte
0xF6,
// MDMCFG4 Modem Configuration
0x83,
// MDMCFG3 Modem Configuration
0x13,
// MDMCFG2 Modem Configuration
0x15,
// DEVIATN Modem Deviation Setting
0x18,
// MCSM0 Main Radio Control State Machine Configuration
0x16,
// FOCCFG Frequency Offset Compensation Configuration
0xFB,
// WORCTRL Wake On Radio Control
0xE9,
// FSCAL3 Frequency Synthesizer Calibration
0x2A,
// FSCAL2 Frequency Synthesizer Calibration
0x00,
// FSCAL1 Frequency Synthesizer Calibration
0x1F,
// FSCAL0 Frequency Synthesizer Calibration
0x81,
// TEST2 Various Test Settings
0x35,
// TEST1 Various Test Settings
0x09,
// TEST0 Various Test Settings
};
halSpiWriteReg(CCxxx0_IOCFG0, rfSettings.iocfg0);
halSpiWriteReg(CCxxx0_FIFOTHR, rfSettings.fifothr);
halSpiWriteReg(CCxxx0_PKTCTRL0, rfSettings.pktctrl0);
halSpiWriteReg(CCxxx0_FSCTRL1, rfSettings.fsctrl1);
halSpiWriteReg(CCxxx0_FREQ2, rfSettings.freq2);
halSpiWriteReg(CCxxx0_FREQ1, rfSettings.freq1);
halSpiWriteReg(CCxxx0_FREQ0, rfSettings.freq0);
halSpiWriteReg(CCxxx0_MDMCFG4, rfSettings.mdmcfg4);
halSpiWriteReg(CCxxx0_MDMCFG3, rfSettings.mdmcfg3);
halSpiWriteReg(CCxxx0_MDMCFG2, rfSettings.mdmcfg2);
halSpiWriteReg(CCxxx0_DEVIATN, rfSettings.deviatn);
halSpiWriteReg(CCxxx0_MCSM0, rfSettings.mcsm0);
halSpiWriteReg(CCxxx0_FOCCFG, rfSettings.foccfg);
halSpiWriteReg(CCxxx0_WORCTRL, rfSettings.worctrl);
halSpiWriteReg(CCxxx0_FSCAL3, rfSettings.fscal3);
halSpiWriteReg(CCxxx0_FSCAL2, rfSettings.fscal2);
halSpiWriteReg(CCxxx0_FSCAL1, rfSettings.fscal1);
halSpiWriteReg(CCxxx0_FSCAL0, rfSettings.fscal0);
halSpiWriteReg(CCxxx0_TEST2, rfSettings.test2);
halSpiWriteReg(CCxxx0_TEST1, rfSettings.test1);
halSpiWriteReg(CCxxx0_TEST0, rfSettings.test0);
}
//*****************************************************************************************
//鍑芥暟鍚嶏細void halRfSendPacket(INT8U *txBuffer, INT8U size)
//杈撳叆锛氬彂閫佺殑缂撳啿鍖猴紝鍙戦€佹暟鎹釜鏁?
//杈撳嚭锛氭棤
//鍔熻兘鎻忚堪锛欳C1100鍙戦€佷竴缁勬暟鎹?
//*****************************************************************************************
void
halRfSendPacket(INT8U *txBuffer, INT8U size)
{
halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_STX);
//杩涘叆鍙戦€佹ā寮忓彂閫佹暟鎹?
halSpiWriteReg(CCxxx0_TXFIFO, size);
halSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size);
//鍐欏叆瑕佸彂閫佺殑鏁版嵁
// Wait for GDO0 to be set -> sync transmitted
while
(!GDO0);
// Wait for GDO0 to be cleared -> end of packet
while
(GDO0);
halSpiStrobe(CCxxx0_SFTX);
halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_SRX);
}
//************************************************************************************************//
//********************************* 鏃犱腑鏂帴鏀跺嚱鏁? ************************************//
//***********************************************************************************************//
INT8U halRfReceivePacket(INT8U *rxBuffer, INT8U *length)
{
INT8U status[2];
INT8U packetLength;
INT8U i=(*length)*4;
// 鍏蜂綋澶氬皯瑕佹牴鎹甦atarate鍜宭ength鏉ュ喅瀹?
halSpiStrobe(CCxxx0_SIDLE);
halSpiStrobe(CCxxx0_SRX);
//杩涘叆鎺ユ敹鐘舵€?
cc1101_delay(20);
while
(GDO0)
{
cc1101_delay(20);
--i;
if
(i<1)
return
0;
}
if
((halSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO))
//濡傛灉鎺ョ殑瀛楄妭鏁颁笉涓?
{
packetLength = halSpiReadReg(CCxxx0_RXFIFO);
//璇诲嚭绗竴涓瓧鑺傦紝姝ゅ瓧鑺備负璇ュ抚鏁版嵁闀垮害
if
(packetLength <= *length)
//濡傛灉鎵€瑕佺殑鏈夋晥鏁版嵁闀垮害灏忎簬绛変簬鎺ユ敹鍒扮殑鏁版嵁鍖呯殑闀垮害
{
halSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength);
//璇诲嚭鎵€鏈夋帴鏀跺埌鐨勬暟鎹?
*length = packetLength;
//鎶婃帴鏀舵暟鎹暱搴︾殑淇敼涓哄綋鍓嶆暟鎹殑闀垮害
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
halSpiReadBurstReg(CCxxx0_RXFIFO, status, 2);
//璇诲嚭CRC鏍¢獙浣?
halSpiStrobe(CCxxx0_SFRX);
//娓呮礂鎺ユ敹缂撳啿鍖?
return
(status[1] & CRC_OK);
//濡傛灉鏍¢獙鎴愬姛杩斿洖鎺ユ敹鎴愬姛
}
else
{
*length = packetLength;
halSpiStrobe(CCxxx0_SFRX);
//娓呮礂鎺ユ敹缂撳啿鍖?
return
0;
}
}
else
return
0;
}
static
int
Init_CC1100(
void
)
{
INT8U PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};
CpuInit();
POWER_UP_RESET_CC1100();
halRfWriteRfSettings();
halSpiWriteBurstReg(CCxxx0_PATABLE, PaTabel, 8);
return
0;
}
/****************************************************************************************/
#define CC1101_BUFLEN 16
static
dev_t cc1101_dev_no = 0;
static
volatile
int
rcv_flag;
/* cc1101设备 */
typedef
struct
tag_cc1101_dev_t
{
struct
cdev cdev;
unsigned
char
cc1101_buf[CC1101_BUFLEN];
wait_queue_head_t read_wait;
}cc1101_dev_t;
static
cc1101_dev_t cc1101_dev;
struct
rcv_irq_desc {
int
irq;
int
pin;
int
pin_setting;
char
*name;
};
static
irqreturn_t cc1101_rcv_interrupt(
int
irq,
void
*dev_id)
{
INT8U count = CC1101_BUFLEN;
int
ret;
printk(
"cc1101 handle interrupt!\n"
);
ret = halRfReceivePacket(cc1101_dev.cc1101_buf, &count);
if
(0 != ret)
{
/*
printk("cc1101 receiving .... start\n");
printk("cc1101 receiving .... end\n");
printk("cc1101 receiving %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
*/
rcv_flag = 1;
wake_up_interruptible(&cc1101_dev.read_wait);
}
return
IRQ_RETVAL(IRQ_HANDLED);
}
static
struct
rcv_irq_desc cc1101_rcv_irq = {
IRQ_EINT15,
S3C2410_GPG7,
S3C2410_GPG7_EINT15,
"spi_GDO0"
};
/*文件打开函数*/
int
cc1101_open(
struct
inode *inode,
struct
file *filp)
{
int
ret;
ret = request_irq(cc1101_rcv_irq.irq, cc1101_rcv_interrupt, IRQ_TYPE_EDGE_FALLING,
cc1101_rcv_irq.name, (
void
*)&cc1101_rcv_irq);
if
(ret)
{
printk(
"request_irq error!\n"
);
return
-EBUSY;
}
return
0;
}
/*写函数*/
static
ssize_t cc1101_write(
struct
file *filp,
const
char
__user *buf,
size_t
size, loff_t *ppos)
{
unsigned
int
count = size;
int
ret = 0;
/*分析和获取有效的写长度*/
if
(CC1101_BUFLEN != size)
{
printk(
"cc1101 write wrong len:%d\n"
, size);
return
-ENOMEM;
}
/*用户空间->内核空间*/
if
(copy_from_user(cc1101_dev.cc1101_buf, buf, count))
ret = - EFAULT;
else
{
ret = count;
//printk("kernel-space: cc1101 written %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
}
/* CC1101硬件发送 */
//printk("kernel-space: cc1101 sending .... start\n");
halRfSendPacket(cc1101_dev.cc1101_buf, count);
//printk("kernel-space: cc1101 sending .... end\n");
return
ret;
}
/* 读函数 */
static
ssize_t cc1101_waitqueue_read(
struct
file *filp,
char
__user *buf,
size_t
size, loff_t *ppos)
{
unsigned
int
count = size;
int
ret = 0;
DECLARE_WAITQUEUE(wait, current);
if
(CC1101_BUFLEN != count)
{
printk(
"kernel-space: cc1101 read wrong len:%d\n"
, count);
return
-ENOMEM;
}
add_wait_queue(&cc1101_dev.read_wait, &wait);
if
(0 == rcv_flag)
{
if
(filp->f_flags & O_NONBLOCK)
{
ret = -EAGAIN;
goto
out;
}
__set_current_state(TASK_INTERRUPTIBLE);
schedule();
if
(signal_pending(current))
{
ret = - ERESTARTSYS;
goto
out;
}
}
/* 内核空间->用户空间 */
copy_to_user(buf, cc1101_dev.cc1101_buf, count);
ret = count;
out:
remove_wait_queue(&cc1101_dev.read_wait, &wait);
set_current_state(TASK_RUNNING);
rcv_flag = 0;
return
ret;
}
/* poll函数 */
static
unsigned
int
cc1101_poll(
struct
file *filp, poll_table *wait)
{
unsigned
int
mask = 0;
poll_wait(filp, &cc1101_dev.read_wait, wait);
if
(1 == rcv_flag)
{
mask |= POLLIN | POLLRDNORM;
printk(
"kernel-space: cc1101_poll rcv_flag = 1!\n"
);
}
return
mask;
}
static
int
cc1101_close(
struct
inode *inode,
struct
file *file)
{
free_irq(cc1101_rcv_irq.irq, (
void
*)&cc1101_rcv_irq);
printk(
"kernel-space: cc1101_close!\n"
);
return
0;
}
struct
file_operations cc1101_fops =
{
.owner = THIS_MODULE,
.open = cc1101_open,
.release = cc1101_close,
.write = cc1101_write,
.read = cc1101_waitqueue_read,
.poll = cc1101_poll,
};
/*初始化并注册cdev*/
static
int
cc1101_setup_cdev(
void
)
{
int
err;
cdev_init(&cc1101_dev.cdev, &cc1101_fops);
cc1101_dev.cdev.owner = THIS_MODULE;
cc1101_dev.cdev.ops = &cc1101_fops;
err = cdev_add(&cc1101_dev.cdev, cc1101_dev_no, 1);
if
(err)
printk(
"cc1101 cc1101_setup_cdev error!"
);
return
err;
}
static
int
__init cc1101_init(
void
)
{
int
ret = 0;
ret = Init_CC1100();
if
(0 != ret)
goto
init_fail;
ret = alloc_chrdev_region(&cc1101_dev_no, 0, 1,
"cc1101"
);
if
(0 < ret)
goto
init_fail;
init_waitqueue_head(&cc1101_dev.read_wait);
ret = cc1101_setup_cdev();
if
(0 != ret)
{
unregister_chrdev_region(cc1101_dev_no, 1);
goto
init_fail;
}
printk(
"cc1101 init success!\n"
);
return
0;
init_fail:
printk(
"cc1101 init failed!\n"
);
return
ret;
}
static
void
__exit cc1101_exit(
void
)
{
unregister_chrdev_region(cc1101_dev_no, 1);
cdev_del(&cc1101_dev.cdev);
printk(
"cc1101 exit success!\n"
);
}
module_init(cc1101_init);
module_exit(cc1101_exit);
MODULE_LICENSE(
"GPL"
);
MODULE_AUTHOR(
"forsakening-hdu"
);
MODULE_DESCRIPTION(
"cc1101 control for EmbedSky TQ2440 Board"
);
linux 驱动cc1101
标签:
原文地址:http://www.cnblogs.com/zym0805/p/4397652.html
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
gitlab 在linux安装环境下存储地址
2021-07-29
当 Mac 未检测到外部显示器时如何修复它
2021-07-29
Ubuntu18.04安装qemu遇到问题-qemu : Depends: qemu-system (>= 1:2.11+dfsg-1ubuntu7)
2021-07-28
[Linux]Shell编程【待续】
2021-07-28
Linux系统资源查看
2021-07-27
Archlinux爬坑指南
2021-07-27
[Linux]Linux发展历程
2021-07-27
非桌面系统 (ubuntu)安装google-chrome
2021-07-27
在Ubuntu18.04系统中源码安装 gcc7.3.0
2021-07-23
Linux快捷键杂记
2021-07-22
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!