linux 驱动cc1101

cc1101.h:

[cpp] view plaincopyprint?

  1. #ifndef _CC1101_H
  2. #define _CC1101_H
  3. #define     INT8U   unsigned char
  4. #define     INT16U  unsigned int
  5. #define     WRITE_BURST         0x40                        //连续写入
  6. #define     READ_SINGLE         0x80                        //读
  7. #define     READ_BURST          0xC0                        //连续读
  8. #define     BYTES_IN_RXFIFO     0x7F                        //接收缓冲区的有效字节数
  9. #define     CRC_OK              0x80                        //CRC校验通过位标志
  10. #define CCxxx0_IOCFG2       0x00        // GDO2 output pin configuration
  11. #define CCxxx0_IOCFG1       0x01        // GDO1 output pin configuration
  12. #define CCxxx0_IOCFG0       0x02        // GDO0 output pin configuration
  13. #define CCxxx0_FIFOTHR      0x03        // RX FIFO and TX FIFO thresholds
  14. #define CCxxx0_SYNC1        0x04        // Sync word, high INT8U
  15. #define CCxxx0_SYNC0        0x05        // Sync word, low INT8U
  16. #define CCxxx0_PKTLEN       0x06        // Packet length
  17. #define CCxxx0_PKTCTRL1     0x07        // Packet automation control
  18. #define CCxxx0_PKTCTRL0     0x08        // Packet automation control
  19. #define CCxxx0_ADDR         0x09        // Device address
  20. #define CCxxx0_CHANNR       0x0A        // Channel number
  21. #define CCxxx0_FSCTRL1      0x0B        // Frequency synthesizer control
  22. #define CCxxx0_FSCTRL0      0x0C        // Frequency synthesizer control
  23. #define CCxxx0_FREQ2        0x0D        // Frequency control word, high INT8U
  24. #define CCxxx0_FREQ1        0x0E        // Frequency control word, middle INT8U
  25. #define CCxxx0_FREQ0        0x0F        // Frequency control word, low INT8U
  26. #define CCxxx0_MDMCFG4      0x10        // Modem configuration
  27. #define CCxxx0_MDMCFG3      0x11        // Modem configuration
  28. #define CCxxx0_MDMCFG2      0x12        // Modem configuration
  29. #define CCxxx0_MDMCFG1      0x13        // Modem configuration
  30. #define CCxxx0_MDMCFG0      0x14        // Modem configuration
  31. #define CCxxx0_DEVIATN      0x15        // Modem deviation setting
  32. #define CCxxx0_MCSM2        0x16        // Main Radio Control State Machine configuration
  33. #define CCxxx0_MCSM1        0x17        // Main Radio Control State Machine configuration
  34. #define CCxxx0_MCSM0        0x18        // Main Radio Control State Machine configuration
  35. #define CCxxx0_FOCCFG       0x19        // Frequency Offset Compensation configuration
  36. #define CCxxx0_BSCFG        0x1A        // Bit Synchronization configuration
  37. #define CCxxx0_AGCCTRL2     0x1B        // AGC control
  38. #define CCxxx0_AGCCTRL1     0x1C        // AGC control
  39. #define CCxxx0_AGCCTRL0     0x1D        // AGC control
  40. #define CCxxx0_WOREVT1      0x1E        // High INT8U Event 0 timeout
  41. #define CCxxx0_WOREVT0      0x1F        // Low INT8U Event 0 timeout
  42. #define CCxxx0_WORCTRL      0x20        // Wake On Radio control
  43. #define CCxxx0_FREND1       0x21        // Front end RX configuration
  44. #define CCxxx0_FREND0       0x22        // Front end TX configuration
  45. #define CCxxx0_FSCAL3       0x23        // Frequency synthesizer calibration
  46. #define CCxxx0_FSCAL2       0x24        // Frequency synthesizer calibration
  47. #define CCxxx0_FSCAL1       0x25        // Frequency synthesizer calibration
  48. #define CCxxx0_FSCAL0       0x26        // Frequency synthesizer calibration
  49. #define CCxxx0_RCCTRL1      0x27        // RC oscillator configuration
  50. #define CCxxx0_RCCTRL0      0x28        // RC oscillator configuration
  51. #define CCxxx0_FSTEST       0x29        // Frequency synthesizer calibration control
  52. #define CCxxx0_PTEST        0x2A        // Production test
  53. #define CCxxx0_AGCTEST      0x2B        // AGC test
  54. #define CCxxx0_TEST2        0x2C        // Various test settings
  55. #define CCxxx0_TEST1        0x2D        // Various test settings
  56. #define CCxxx0_TEST0        0x2E        // Various test settings
  57. // Strobe commands
  58. #define CCxxx0_SRES         0x30        // Reset chip.
  59. #define CCxxx0_SFSTXON      0x31        // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
  60. // If in RX/TX: Go to a wait state where only the synthesizer is
  61. // running (for quick RX / TX turnaround).
  62. #define CCxxx0_SXOFF        0x32        // Turn off crystal oscillator.
  63. #define CCxxx0_SCAL         0x33        // Calibrate frequency synthesizer and turn it off
  64. // (enables quick start).
  65. #define CCxxx0_SRX          0x34        // Enable RX. Perform calibration first if coming from IDLE and
  66. // MCSM0.FS_AUTOCAL=1.
  67. #define CCxxx0_STX          0x35        // In IDLE state: Enable TX. Perform calibration first if
  68. // MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
  69. // Only go to TX if channel is clear.
  70. #define CCxxx0_SIDLE        0x36        // Exit RX / TX, turn off frequency synthesizer and exit
  71. // Wake-On-Radio mode if applicable.
  72. #define CCxxx0_SAFC         0x37        // Perform AFC adjustment of the frequency synthesizer
  73. #define CCxxx0_SWOR         0x38        // Start automatic RX polling sequence (Wake-on-Radio)
  74. #define CCxxx0_SPWD         0x39        // Enter power down mode when CSn goes high.
  75. #define CCxxx0_SFRX         0x3A        // Flush the RX FIFO buffer.
  76. #define CCxxx0_SFTX         0x3B        // Flush the TX FIFO buffer.
  77. #define CCxxx0_SWORRST      0x3C        // Reset real time clock.
  78. #define CCxxx0_SNOP         0x3D        // No operation. May be used to pad strobe commands to two
  79. // INT8Us for simpler software.
  80. #define CCxxx0_PARTNUM      0x30
  81. #define CCxxx0_VERSION      0x31
  82. #define CCxxx0_FREQEST      0x32
  83. #define CCxxx0_LQI          0x33
  84. #define CCxxx0_RSSI         0x34
  85. #define CCxxx0_MARCSTATE    0x35
  86. #define CCxxx0_WORTIME1     0x36
  87. #define CCxxx0_WORTIME0     0x37
  88. #define CCxxx0_PKTSTATUS    0x38
  89. #define CCxxx0_VCO_VC_DAC   0x39
  90. #define CCxxx0_TXBYTES      0x3A
  91. #define CCxxx0_RXBYTES      0x3B
  92. #define CCxxx0_PATABLE      0x3E
  93. #define CCxxx0_TXFIFO       0x3F
  94. #define CCxxx0_RXFIFO       0x3F
  95. // RF_SETTINGS is a data structure which contains all relevant CCxxx0 registers
  96. typedef struct {
  97. INT8U iocfg0;     // GDO0 Output Pin Configuration
  98. INT8U fifothr;    // RX FIFO and TX FIFO Thresholds
  99. INT8U pktctrl0;   // Packet Automation Control
  100. INT8U fsctrl1;    // Frequency Synthesizer Control
  101. INT8U freq2;      // Frequency Control Word, High Byte
  102. INT8U freq1;      // Frequency Control Word, Middle Byte
  103. INT8U freq0;      // Frequency Control Word, Low Byte
  104. INT8U mdmcfg4;    // Modem Configuration
  105. INT8U mdmcfg3;    // Modem Configuration
  106. INT8U mdmcfg2;    // Modem Configuration
  107. INT8U deviatn;    // Modem Deviation Setting
  108. INT8U mcsm0;      // Main Radio Control State Machine Configuration
  109. INT8U foccfg;     // Frequency Offset Compensation Configuration
  110. INT8U worctrl;    // Wake On Radio Control
  111. INT8U fscal3;     // Frequency Synthesizer Calibration
  112. INT8U fscal2;     // Frequency Synthesizer Calibration
  113. INT8U fscal1;     // Frequency Synthesizer Calibration
  114. INT8U fscal0;     // Frequency Synthesizer Calibration
  115. INT8U test2;      // Various Test Settings
  116. INT8U test1;      // Various Test Settings
  117. INT8U test0;      // Various Test Settings
  118. } RF_SETTINGS;
  119. #endif
  120. cc1101.c

    [cpp] view plaincopyprint?

    1. #include <linux/module.h>
    2. #include <linux/moduleparam.h>
    3. #include <linux/init.h>
    4. #include <linux/sched.h>
    5. #include <linux/kernel.h> /* printk() */
    6. #include <linux/slab.h>       /* kmalloc() */
    7. #include <linux/fs.h>     /* everything... */
    8. #include <linux/errno.h>  /* error codes */
    9. #include <linux/types.h>  /* size_t */
    10. #include <linux/proc_fs.h>
    11. #include <linux/fcntl.h>  /* O_ACCMODE */
    12. #include <linux/seq_file.h>
    13. #include <linux/cdev.h>
    14. #include <linux/poll.h>
    15. #include <linux/irq.h>
    16. #include <asm/irq.h>
    17. #include <linux/interrupt.h>
    18. #include <asm/uaccess.h>
    19. #include <mach/regs-gpio.h>
    20. #include <mach/hardware.h>
    21. #include <linux/platform_device.h>
    22. #include <asm/system.h>       /* cli(), *_flags */
    23. #include <asm/uaccess.h>  /* copy_*_user */
    24. #include "cc1101.h"
    25. int nop_tmp;
    26. typedef struct cc1101_spi_pin_t
    27. {
    28. unsigned long spi_SCK;     /* GPF4 = SCK 输出 */
    29. unsigned long spi_MOSI;    /* GPF3 = MOSI 输出 */
    30. unsigned long spi_GDO2;    /* GPG6 = GD02 输出 */
    31. unsigned long spi_MISO;    /* GPG5 = MISO 输入 */
    32. unsigned long spi_CSN;     /* GPG11 = CSN 输出 */
    33. unsigned long spi_GDO0;    /* GPG7 = GD01 输入类型 */
    34. }cc1101_spi_pin;
    35. typedef struct cc1101_spi_pintype_t
    36. {
    37. unsigned long spi_SCK;     /* GPF4 = SCK 输出 */
    38. unsigned long spi_MOSI;    /* GPF3 = MOSI 输出 */
    39. unsigned long spi_GDO2;    /* GPG6 = GD02 输出 */
    40. unsigned long spi_MISO;    /* GPG5 = MISO 输入 */
    41. unsigned long spi_CSN;     /* GPG11 = CSN 输出 */
    42. unsigned long spi_GDO0;    /* GPG7 = GD01 下降沿中断类型 */
    43. }cc1101_spi_pintype;
    44. static cc1101_spi_pin cc1101_pin = {
    45. S3C2410_GPF4,
    46. S3C2410_GPF3,
    47. S3C2410_GPG6,
    48. S3C2410_GPG5,
    49. S3C2410_GPG11,
    50. S3C2410_GPG7,
    51. };
    52. static cc1101_spi_pintype cc1101_pintype = {
    53. S3C2410_GPF4_OUTP,
    54. S3C2410_GPF3_OUTP,
    55. S3C2410_GPG6_OUTP,
    56. S3C2410_GPG5_INP,
    57. S3C2410_GPG11_OUTP,
    58. S3C2410_GPG7_EINT15,
    59. };
    60. #define MISO s3c2410_gpio_getpin(cc1101_pin.spi_MISO)
    61. #define GDO0 s3c2410_gpio_getpin(cc1101_pin.spi_GDO0)
    62. #define MOSI_H s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 1)
    63. #define MOSI_L s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 0)
    64. #define CSN_H s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 1)
    65. #define CSN_L s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 0)
    66. #define SCK_H s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 1)
    67. #define SCK_L s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 0)
    68. #define GDO2_H s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 1)
    69. #define GDO2_L s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 0)
    70. void soc_init(void)
    71. {
    72. s3c2410_gpio_cfgpin(cc1101_pin.spi_SCK, cc1101_pintype.spi_SCK);
    73. s3c2410_gpio_cfgpin(cc1101_pin.spi_MOSI, cc1101_pintype.spi_MOSI);
    74. s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO2, cc1101_pintype.spi_GDO2);
    75. s3c2410_gpio_cfgpin(cc1101_pin.spi_MISO, cc1101_pintype.spi_MISO);
    76. s3c2410_gpio_cfgpin(cc1101_pin.spi_CSN, cc1101_pintype.spi_CSN);
    77. s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO0, cc1101_pintype.spi_GDO0);
    78. printk("cc1101 set pin ok!");
    79. }
    80. static void cc1101_delay(unsigned int s)
    81. {
    82. unsigned int i;
    83. for(i = 0; i < s; i++);
    84. for(i = 0; i < s; i++);
    85. }
    86. void halWait(INT16U timeout)
    87. {
    88. int i;
    89. do
    90. {
    91. for(i = 0; i < 150; i++)
    92. nop_tmp++;
    93. }
    94. while (--timeout);
    95. }
    96. void SpiInit(void)
    97. {
    98. CSN_L;
    99. SCK_L;
    100. CSN_H;
    101. }
    102. /*****************************************************************************************/
    103. //鍑芥暟鍚嶏細CpuInit()
    104. //杈撳叆锛氭棤
    105. //杈撳嚭锛氭棤
    106. //鍔熻兘鎻忚堪锛歋PI鍒濆鍖栫▼搴?
    107. /*****************************************************************************************/
    108. void CpuInit(void)
    109. {
    110. soc_init();
    111. SpiInit();
    112. cc1101_delay(1500000);
    113. }
    114. //*****************************************************************************************
    115. //鍑芥暟鍚嶏細SpisendByte(INT8U dat)
    116. //杈撳叆锛氬彂閫佺殑鏁版嵁
    117. //杈撳嚭锛氭棤
    118. //鍔熻兘鎻忚堪锛歋PI鍙戦€佷竴涓瓧鑺?
    119. //*****************************************************************************************
    120. INT8U SpiTxRxByte(INT8U dat)
    121. {
    122. INT8U i,temp;
    123. temp = 0;
    124. SCK_L;
    125. for(i=0; i<8; i++)
    126. {
    127. if(dat & 0x80)
    128. {
    129. MOSI_H;
    130. }
    131. else MOSI_L;
    132. dat <<= 1;
    133. SCK_H;
    134. nop_tmp++;
    135. nop_tmp++;
    136. nop_tmp++;
    137. nop_tmp++;
    138. nop_tmp++;
    139. nop_tmp++;
    140. temp <<= 1;
    141. if(MISO)temp++;
    142. SCK_L;
    143. nop_tmp++;
    144. nop_tmp++;
    145. nop_tmp++;
    146. nop_tmp++;
    147. nop_tmp++;
    148. nop_tmp++;
    149. }
    150. return temp;
    151. }
    152. //*****************************************************************************************
    153. //鍑芥暟鍚嶏細void RESET_CC1100(void)
    154. //杈撳叆锛氭棤
    155. //杈撳嚭锛氭棤
    156. //鍔熻兘鎻忚堪锛氬浣岰C1100
    157. //*****************************************************************************************
    158. void RESET_CC1100(void)
    159. {
    160. CSN_L;
    161. while (MISO);
    162. SpiTxRxByte(CCxxx0_SRES);       //鍐欏叆澶嶄綅鍛戒护
    163. while (MISO);
    164. CSN_H;
    165. }
    166. //*****************************************************************************************
    167. //鍑芥暟鍚嶏細void POWER_UP_RESET_CC1100(void)
    168. //杈撳叆锛氭棤
    169. //杈撳嚭锛氭棤
    170. //鍔熻兘鎻忚堪锛氫笂鐢靛浣岰C1100
    171. //*****************************************************************************************
    172. void POWER_UP_RESET_CC1100(void)
    173. {
    174. CSN_H;
    175. halWait(10);
    176. CSN_L;
    177. halWait(10);
    178. CSN_H;
    179. halWait(410);
    180. RESET_CC1100();         //澶嶄綅CC1100
    181. }
    182. //*****************************************************************************************
    183. //鍑芥暟鍚嶏細void halSpiWriteReg(INT8U addr, INT8U value)
    184. //杈撳叆锛氬湴鍧€鍜岄厤缃瓧
    185. //杈撳嚭锛氭棤
    186. //鍔熻兘鎻忚堪锛歋PI鍐欏瘎瀛樺櫒
    187. //*****************************************************************************************
    188. void halSpiWriteReg(INT8U addr, INT8U value)
    189. {
    190. CSN_L;
    191. while (MISO);
    192. SpiTxRxByte(addr);      //鍐欏湴鍧€
    193. SpiTxRxByte(value);     //鍐欏叆閰嶇疆
    194. CSN_H;
    195. }
    196. //*****************************************************************************************
    197. //鍑芥暟鍚嶏細void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
    198. //杈撳叆锛氬湴鍧€锛屽啓鍏ョ紦鍐插尯锛屽啓鍏ヤ釜鏁?
    199. //杈撳嚭锛氭棤
    200. //鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
    201. //*****************************************************************************************
    202. void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
    203. {
    204. INT8U i, temp;
    205. temp = addr | WRITE_BURST;
    206. CSN_L;
    207. while (MISO);
    208. SpiTxRxByte(temp);
    209. for (i = 0; i < count; i++)
    210. {
    211. SpiTxRxByte(buffer[i]);
    212. }
    213. CSN_H;
    214. }
    215. //*****************************************************************************************
    216. //鍑芥暟鍚嶏細void halSpiStrobe(INT8U strobe)
    217. //杈撳叆锛氬懡浠?
    218. //杈撳嚭锛氭棤
    219. //鍔熻兘鎻忚堪锛歋PI鍐欏懡浠?
    220. //*****************************************************************************************
    221. void halSpiStrobe(INT8U strobe)
    222. {
    223. CSN_L;
    224. while (MISO);
    225. SpiTxRxByte(strobe);        //鍐欏叆鍛戒护
    226. CSN_H;
    227. }
    228. //*****************************************************************************************
    229. //鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
    230. //杈撳叆锛氬湴鍧€
    231. //杈撳嚭锛氳瀵勫瓨鍣ㄧ殑閰嶇疆瀛?
    232. //鍔熻兘鎻忚堪锛歋PI璇诲瘎瀛樺櫒
    233. //*****************************************************************************************
    234. INT8U halSpiReadReg(INT8U addr)
    235. {
    236. INT8U temp, value;
    237. temp = addr|READ_SINGLE;//璇诲瘎瀛樺櫒鍛戒护
    238. CSN_L;
    239. while (MISO);
    240. SpiTxRxByte(temp);
    241. value = SpiTxRxByte(0);
    242. CSN_H;
    243. return value;
    244. }
    245. //*****************************************************************************************
    246. //鍑芥暟鍚嶏細void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
    247. //杈撳叆锛氬湴鍧€锛岃鍑烘暟鎹悗鏆傚瓨鐨勭紦鍐插尯锛岃鍑洪厤缃釜鏁?
    248. //杈撳嚭锛氭棤
    249. //鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
    250. //*****************************************************************************************
    251. void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
    252. {
    253. INT8U i,temp;
    254. temp = addr | READ_BURST;       //鍐欏叆瑕佽鐨勯厤缃瘎瀛樺櫒鍦板潃鍜岃鍛戒护
    255. CSN_L;
    256. while (MISO);
    257. SpiTxRxByte(temp);
    258. for (i = 0; i < count; i++)
    259. {
    260. buffer[i] = SpiTxRxByte(0);
    261. }
    262. CSN_H;
    263. }
    264. //*****************************************************************************************
    265. //鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
    266. //杈撳叆锛氬湴鍧€
    267. //杈撳嚭锛氳鐘舵€佸瘎瀛樺櫒褰撳墠鍊?
    268. //鍔熻兘鎻忚堪锛歋PI璇荤姸鎬佸瘎瀛樺櫒
    269. //*****************************************************************************************
    270. INT8U halSpiReadStatus(INT8U addr)
    271. {
    272. INT8U value,temp;
    273. temp = addr | READ_BURST;       //鍐欏叆瑕佽鐨勭姸鎬佸瘎瀛樺櫒鐨勫湴鍧€鍚屾椂鍐欏叆璇诲懡浠?
    274. CSN_L;
    275. while (MISO);
    276. SpiTxRxByte(temp);
    277. value = SpiTxRxByte(0);
    278. CSN_H;
    279. return value;
    280. }
    281. //*****************************************************************************************
    282. //鍑芥暟鍚嶏細void halRfWriteRfSettings(RF_SETTINGS *pRfSettings)
    283. //杈撳叆锛氭棤
    284. //杈撳嚭锛氭棤
    285. //鍔熻兘鎻忚堪锛氶厤缃瓹C1100鐨勫瘎瀛樺櫒
    286. //*****************************************************************************************
    287. void halRfWriteRfSettings(void)
    288. {
    289. //*******************************此rfSettings配置来自Smart RF***********************************//
    290. //*******************************Low data rate----2.4kbaud**************************************//
    291. //*******************************Carrier frequency-----433.99MHz********************************//
    292. RF_SETTINGS rfSettings = {
    293. 0x06,  // IOCFG0        GDO0 Output Pin Configuration
    294. 0x47,  // FIFOTHR       RX FIFO and TX FIFO Thresholds
    295. 0x05,  // PKTCTRL0      Packet Automation Control
    296. 0x06,  // FSCTRL1       Frequency Synthesizer Control
    297. 0x10,  // FREQ2         Frequency Control Word, High Byte
    298. 0xB1,  // FREQ1         Frequency Control Word, Middle Byte
    299. 0x3B,  // FREQ0         Frequency Control Word, Low Byte
    300. 0xF6,  // MDMCFG4       Modem Configuration
    301. 0x83,  // MDMCFG3       Modem Configuration
    302. 0x13,  // MDMCFG2       Modem Configuration
    303. 0x15,  // DEVIATN       Modem Deviation Setting
    304. 0x18,  // MCSM0         Main Radio Control State Machine Configuration
    305. 0x16,  // FOCCFG        Frequency Offset Compensation Configuration
    306. 0xFB,  // WORCTRL       Wake On Radio Control
    307. 0xE9,  // FSCAL3        Frequency Synthesizer Calibration
    308. 0x2A,  // FSCAL2        Frequency Synthesizer Calibration
    309. 0x00,  // FSCAL1        Frequency Synthesizer Calibration
    310. 0x1F,  // FSCAL0        Frequency Synthesizer Calibration
    311. 0x81,  // TEST2         Various Test Settings
    312. 0x35,  // TEST1         Various Test Settings
    313. 0x09,  // TEST0         Various Test Settings
    314. };
    315. halSpiWriteReg(CCxxx0_IOCFG0,   rfSettings.iocfg0);
    316. halSpiWriteReg(CCxxx0_FIFOTHR,   rfSettings.fifothr);
    317. halSpiWriteReg(CCxxx0_PKTCTRL0,   rfSettings.pktctrl0);
    318. halSpiWriteReg(CCxxx0_FSCTRL1,   rfSettings.fsctrl1);
    319. halSpiWriteReg(CCxxx0_FREQ2,   rfSettings.freq2);
    320. halSpiWriteReg(CCxxx0_FREQ1,   rfSettings.freq1);
    321. halSpiWriteReg(CCxxx0_FREQ0,   rfSettings.freq0);
    322. halSpiWriteReg(CCxxx0_MDMCFG4,   rfSettings.mdmcfg4);
    323. halSpiWriteReg(CCxxx0_MDMCFG3,   rfSettings.mdmcfg3);
    324. halSpiWriteReg(CCxxx0_MDMCFG2,   rfSettings.mdmcfg2);
    325. halSpiWriteReg(CCxxx0_DEVIATN,   rfSettings.deviatn);
    326. halSpiWriteReg(CCxxx0_MCSM0,   rfSettings.mcsm0);
    327. halSpiWriteReg(CCxxx0_FOCCFG,   rfSettings.foccfg);
    328. halSpiWriteReg(CCxxx0_WORCTRL,   rfSettings.worctrl);
    329. halSpiWriteReg(CCxxx0_FSCAL3,   rfSettings.fscal3);
    330. halSpiWriteReg(CCxxx0_FSCAL2,   rfSettings.fscal2);
    331. halSpiWriteReg(CCxxx0_FSCAL1,   rfSettings.fscal1);
    332. halSpiWriteReg(CCxxx0_FSCAL0,   rfSettings.fscal0);
    333. halSpiWriteReg(CCxxx0_TEST2,   rfSettings.test2);
    334. halSpiWriteReg(CCxxx0_TEST1,   rfSettings.test1);
    335. halSpiWriteReg(CCxxx0_TEST0,   rfSettings.test0);
    336. }
    337. //*****************************************************************************************
    338. //鍑芥暟鍚嶏細void halRfSendPacket(INT8U *txBuffer, INT8U size)
    339. //杈撳叆锛氬彂閫佺殑缂撳啿鍖猴紝鍙戦€佹暟鎹釜鏁?
    340. //杈撳嚭锛氭棤
    341. //鍔熻兘鎻忚堪锛欳C1100鍙戦€佷竴缁勬暟鎹?
    342. //*****************************************************************************************
    343. void halRfSendPacket(INT8U *txBuffer, INT8U size)
    344. {
    345. halSpiStrobe(CCxxx0_SIDLE);
    346. halSpiStrobe(CCxxx0_STX);       //杩涘叆鍙戦€佹ā寮忓彂閫佹暟鎹?
    347. halSpiWriteReg(CCxxx0_TXFIFO, size);
    348. halSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size); //鍐欏叆瑕佸彂閫佺殑鏁版嵁
    349. // Wait for GDO0 to be set -> sync transmitted
    350. while (!GDO0);
    351. // Wait for GDO0 to be cleared -> end of packet
    352. while (GDO0);
    353. halSpiStrobe(CCxxx0_SFTX);
    354. halSpiStrobe(CCxxx0_SIDLE);
    355. halSpiStrobe(CCxxx0_SRX);
    356. }
    357. //************************************************************************************************//
    358. //*********************************      鏃犱腑鏂帴鏀跺嚱鏁?     ************************************//
    359. //***********************************************************************************************//
    360. INT8U halRfReceivePacket(INT8U *rxBuffer, INT8U *length)
    361. {
    362. INT8U status[2];
    363. INT8U packetLength;
    364. INT8U i=(*length)*4;  // 鍏蜂綋澶氬皯瑕佹牴鎹甦atarate鍜宭ength鏉ュ喅瀹?
    365. halSpiStrobe(CCxxx0_SIDLE);
    366. halSpiStrobe(CCxxx0_SRX);       //杩涘叆鎺ユ敹鐘舵€?
    367. cc1101_delay(20);
    368. while (GDO0)
    369. {
    370. cc1101_delay(20);
    371. --i;
    372. if(i<1)
    373. return 0;
    374. }
    375. if ((halSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO)) //濡傛灉鎺ョ殑瀛楄妭鏁颁笉涓?
    376. {
    377. packetLength = halSpiReadReg(CCxxx0_RXFIFO);//璇诲嚭绗竴涓瓧鑺傦紝姝ゅ瓧鑺備负璇ュ抚鏁版嵁闀垮害
    378. if (packetLength <= *length)         //濡傛灉鎵€瑕佺殑鏈夋晥鏁版嵁闀垮害灏忎簬绛変簬鎺ユ敹鍒扮殑鏁版嵁鍖呯殑闀垮害
    379. {
    380. halSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength); //璇诲嚭鎵€鏈夋帴鏀跺埌鐨勬暟鎹?
    381. *length = packetLength;             //鎶婃帴鏀舵暟鎹暱搴︾殑淇敼涓哄綋鍓嶆暟鎹殑闀垮害
    382. // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
    383. halSpiReadBurstReg(CCxxx0_RXFIFO, status, 2);   //璇诲嚭CRC鏍¢獙浣?
    384. halSpiStrobe(CCxxx0_SFRX);      //娓呮礂鎺ユ敹缂撳啿鍖?
    385. return (status[1] & CRC_OK);            //濡傛灉鏍¢獙鎴愬姛杩斿洖鎺ユ敹鎴愬姛
    386. }
    387. else
    388. {
    389. *length = packetLength;
    390. halSpiStrobe(CCxxx0_SFRX);      //娓呮礂鎺ユ敹缂撳啿鍖?
    391. return 0;
    392. }
    393. }
    394. else
    395. return 0;
    396. }
    397. static int Init_CC1100(void)
    398. {
    399. INT8U PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};
    400. CpuInit();
    401. POWER_UP_RESET_CC1100();
    402. halRfWriteRfSettings();
    403. halSpiWriteBurstReg(CCxxx0_PATABLE, PaTabel, 8);
    404. return 0;
    405. }
    406. /****************************************************************************************/
    407. #define CC1101_BUFLEN 16
    408. static dev_t cc1101_dev_no = 0;
    409. static volatile int rcv_flag;
    410. /* cc1101设备 */
    411. typedef struct tag_cc1101_dev_t
    412. {
    413. struct cdev cdev;
    414. unsigned char cc1101_buf[CC1101_BUFLEN];
    415. wait_queue_head_t read_wait;
    416. }cc1101_dev_t;
    417. static cc1101_dev_t cc1101_dev;
    418. struct rcv_irq_desc {
    419. int irq;
    420. int pin;
    421. int pin_setting;
    422. char *name;
    423. };
    424. static irqreturn_t cc1101_rcv_interrupt(int irq, void *dev_id)
    425. {
    426. INT8U count = CC1101_BUFLEN;
    427. int ret;
    428. printk("cc1101 handle interrupt!\n");
    429. ret = halRfReceivePacket(cc1101_dev.cc1101_buf, &count);
    430. if (0 != ret)
    431. {
    432. /*
    433. printk("cc1101 receiving .... start\n");
    434. printk("cc1101 receiving .... end\n");
    435. printk("cc1101 receiving %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
    436. */
    437. rcv_flag = 1;
    438. wake_up_interruptible(&cc1101_dev.read_wait);
    439. }
    440. return IRQ_RETVAL(IRQ_HANDLED);
    441. }
    442. static struct rcv_irq_desc cc1101_rcv_irq = {
    443. IRQ_EINT15,
    444. S3C2410_GPG7,
    445. S3C2410_GPG7_EINT15,
    446. "spi_GDO0"};
    447. /*文件打开函数*/
    448. int cc1101_open(struct inode *inode, struct file *filp)
    449. {
    450. int ret;
    451. ret = request_irq(cc1101_rcv_irq.irq, cc1101_rcv_interrupt, IRQ_TYPE_EDGE_FALLING,
    452. cc1101_rcv_irq.name, (void *)&cc1101_rcv_irq);
    453. if (ret)
    454. {
    455. printk("request_irq error!\n");
    456. return -EBUSY;
    457. }
    458. return 0;
    459. }
    460. /*写函数*/
    461. static ssize_t cc1101_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
    462. {
    463. unsigned int count = size;
    464. int ret = 0;
    465. /*分析和获取有效的写长度*/
    466. if (CC1101_BUFLEN != size)
    467. {
    468. printk("cc1101 write wrong len:%d\n", size);
    469. return -ENOMEM;
    470. }
    471. /*用户空间->内核空间*/
    472. if (copy_from_user(cc1101_dev.cc1101_buf, buf, count))
    473. ret =  - EFAULT;
    474. else
    475. {
    476. ret = count;
    477. //printk("kernel-space: cc1101 written %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
    478. }
    479. /* CC1101硬件发送 */
    480. //printk("kernel-space: cc1101 sending .... start\n");
    481. halRfSendPacket(cc1101_dev.cc1101_buf, count);
    482. //printk("kernel-space: cc1101 sending .... end\n");
    483. return ret;
    484. }
    485. /* 读函数 */
    486. static ssize_t cc1101_waitqueue_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
    487. {
    488. unsigned int count = size;
    489. int ret = 0;
    490. DECLARE_WAITQUEUE(wait, current);
    491. if (CC1101_BUFLEN != count)
    492. {
    493. printk("kernel-space: cc1101 read wrong len:%d\n", count);
    494. return -ENOMEM;
    495. }
    496. add_wait_queue(&cc1101_dev.read_wait, &wait);
    497. if (0 == rcv_flag)
    498. {
    499. if (filp->f_flags & O_NONBLOCK)
    500. {
    501. ret = -EAGAIN;
    502. goto out;
    503. }
    504. __set_current_state(TASK_INTERRUPTIBLE);
    505. schedule();
    506. if (signal_pending(current))
    507. {
    508. ret =  - ERESTARTSYS;
    509. goto out;
    510. }
    511. }
    512. /* 内核空间->用户空间 */
    513. copy_to_user(buf, cc1101_dev.cc1101_buf, count);
    514. ret = count;
    515. out:
    516. remove_wait_queue(&cc1101_dev.read_wait, &wait);
    517. set_current_state(TASK_RUNNING);
    518. rcv_flag = 0;
    519. return ret;
    520. }
    521. /* poll函数 */
    522. static unsigned int cc1101_poll(struct file *filp, poll_table *wait)
    523. {
    524. unsigned int mask = 0;
    525. poll_wait(filp, &cc1101_dev.read_wait, wait);
    526. if (1 == rcv_flag)
    527. {
    528. mask |= POLLIN | POLLRDNORM;
    529. printk("kernel-space: cc1101_poll rcv_flag = 1!\n");
    530. }
    531. return mask;
    532. }
    533. static int cc1101_close(struct inode *inode, struct file *file)
    534. {
    535. free_irq(cc1101_rcv_irq.irq, (void *)&cc1101_rcv_irq);
    536. printk("kernel-space: cc1101_close!\n");
    537. return 0;
    538. }
    539. struct file_operations cc1101_fops =
    540. {
    541. .owner = THIS_MODULE,
    542. .open = cc1101_open,
    543. .release = cc1101_close,
    544. .write = cc1101_write,
    545. .read = cc1101_waitqueue_read,
    546. .poll = cc1101_poll,
    547. };
    548. /*初始化并注册cdev*/
    549. static int cc1101_setup_cdev(void)
    550. {
    551. int err;
    552. cdev_init(&cc1101_dev.cdev, &cc1101_fops);
    553. cc1101_dev.cdev.owner = THIS_MODULE;
    554. cc1101_dev.cdev.ops = &cc1101_fops;
    555. err = cdev_add(&cc1101_dev.cdev, cc1101_dev_no, 1);
    556. if (err)
    557. printk("cc1101 cc1101_setup_cdev error!");
    558. return err;
    559. }
    560. static int __init cc1101_init(void)
    561. {
    562. int ret = 0;
    563. ret = Init_CC1100();
    564. if (0 != ret)
    565. goto init_fail;
    566. ret = alloc_chrdev_region(&cc1101_dev_no, 0, 1, "cc1101");
    567. if (0 < ret)
    568. goto init_fail;
    569. init_waitqueue_head(&cc1101_dev.read_wait);
    570. ret = cc1101_setup_cdev();
    571. if (0 != ret)
    572. {
    573. unregister_chrdev_region(cc1101_dev_no, 1);
    574. goto init_fail;
    575. }
    576. printk("cc1101 init success!\n");
    577. return 0;
    578. init_fail:
    579. printk("cc1101 init failed!\n");
    580. return ret;
    581. }
    582. static void  __exit cc1101_exit(void)
    583. {
    584. unregister_chrdev_region(cc1101_dev_no, 1);
    585. cdev_del(&cc1101_dev.cdev);
    586. printk("cc1101 exit success!\n");
    587. }
    588. module_init(cc1101_init);
    589. module_exit(cc1101_exit);
    590. MODULE_LICENSE("GPL");
    591. MODULE_AUTHOR("forsakening-hdu");
    592. MODULE_DESCRIPTION("cc1101 control for EmbedSky TQ2440 Board");

cc1101.c

[cpp] view plaincopyprint?

  1. #include <linux/module.h>
  2. #include <linux/moduleparam.h>
  3. #include <linux/init.h>
  4. #include <linux/sched.h>
  5. #include <linux/kernel.h> /* printk() */
  6. #include <linux/slab.h>       /* kmalloc() */
  7. #include <linux/fs.h>     /* everything... */
  8. #include <linux/errno.h>  /* error codes */
  9. #include <linux/types.h>  /* size_t */
  10. #include <linux/proc_fs.h>
  11. #include <linux/fcntl.h>  /* O_ACCMODE */
  12. #include <linux/seq_file.h>
  13. #include <linux/cdev.h>
  14. #include <linux/poll.h>
  15. #include <linux/irq.h>
  16. #include <asm/irq.h>
  17. #include <linux/interrupt.h>
  18. #include <asm/uaccess.h>
  19. #include <mach/regs-gpio.h>
  20. #include <mach/hardware.h>
  21. #include <linux/platform_device.h>
  22. #include <asm/system.h>       /* cli(), *_flags */
  23. #include <asm/uaccess.h>  /* copy_*_user */
  24. #include "cc1101.h"
  25. int nop_tmp;
  26. typedef struct cc1101_spi_pin_t
  27. {
  28. unsigned long spi_SCK;     /* GPF4 = SCK 输出 */
  29. unsigned long spi_MOSI;    /* GPF3 = MOSI 输出 */
  30. unsigned long spi_GDO2;    /* GPG6 = GD02 输出 */
  31. unsigned long spi_MISO;    /* GPG5 = MISO 输入 */
  32. unsigned long spi_CSN;     /* GPG11 = CSN 输出 */
  33. unsigned long spi_GDO0;    /* GPG7 = GD01 输入类型 */
  34. }cc1101_spi_pin;
  35. typedef struct cc1101_spi_pintype_t
  36. {
  37. unsigned long spi_SCK;     /* GPF4 = SCK 输出 */
  38. unsigned long spi_MOSI;    /* GPF3 = MOSI 输出 */
  39. unsigned long spi_GDO2;    /* GPG6 = GD02 输出 */
  40. unsigned long spi_MISO;    /* GPG5 = MISO 输入 */
  41. unsigned long spi_CSN;     /* GPG11 = CSN 输出 */
  42. unsigned long spi_GDO0;    /* GPG7 = GD01 下降沿中断类型 */
  43. }cc1101_spi_pintype;
  44. static cc1101_spi_pin cc1101_pin = {
  45. S3C2410_GPF4,
  46. S3C2410_GPF3,
  47. S3C2410_GPG6,
  48. S3C2410_GPG5,
  49. S3C2410_GPG11,
  50. S3C2410_GPG7,
  51. };
  52. static cc1101_spi_pintype cc1101_pintype = {
  53. S3C2410_GPF4_OUTP,
  54. S3C2410_GPF3_OUTP,
  55. S3C2410_GPG6_OUTP,
  56. S3C2410_GPG5_INP,
  57. S3C2410_GPG11_OUTP,
  58. S3C2410_GPG7_EINT15,
  59. };
  60. #define MISO s3c2410_gpio_getpin(cc1101_pin.spi_MISO)
  61. #define GDO0 s3c2410_gpio_getpin(cc1101_pin.spi_GDO0)
  62. #define MOSI_H s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 1)
  63. #define MOSI_L s3c2410_gpio_setpin(cc1101_pin.spi_MOSI, 0)
  64. #define CSN_H s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 1)
  65. #define CSN_L s3c2410_gpio_setpin(cc1101_pin.spi_CSN, 0)
  66. #define SCK_H s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 1)
  67. #define SCK_L s3c2410_gpio_setpin(cc1101_pin.spi_SCK, 0)
  68. #define GDO2_H s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 1)
  69. #define GDO2_L s3c2410_gpio_setpin(cc1101_pin.spi_GDO2, 0)
  70. void soc_init(void)
  71. {
  72. s3c2410_gpio_cfgpin(cc1101_pin.spi_SCK, cc1101_pintype.spi_SCK);
  73. s3c2410_gpio_cfgpin(cc1101_pin.spi_MOSI, cc1101_pintype.spi_MOSI);
  74. s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO2, cc1101_pintype.spi_GDO2);
  75. s3c2410_gpio_cfgpin(cc1101_pin.spi_MISO, cc1101_pintype.spi_MISO);
  76. s3c2410_gpio_cfgpin(cc1101_pin.spi_CSN, cc1101_pintype.spi_CSN);
  77. s3c2410_gpio_cfgpin(cc1101_pin.spi_GDO0, cc1101_pintype.spi_GDO0);
  78. printk("cc1101 set pin ok!");
  79. }
  80. static void cc1101_delay(unsigned int s)
  81. {
  82. unsigned int i;
  83. for(i = 0; i < s; i++);
  84. for(i = 0; i < s; i++);
  85. }
  86. void halWait(INT16U timeout)
  87. {
  88. int i;
  89. do
  90. {
  91. for(i = 0; i < 150; i++)
  92. nop_tmp++;
  93. }
  94. while (--timeout);
  95. }
  96. void SpiInit(void)
  97. {
  98. CSN_L;
  99. SCK_L;
  100. CSN_H;
  101. }
  102. /*****************************************************************************************/
  103. //鍑芥暟鍚嶏細CpuInit()
  104. //杈撳叆锛氭棤
  105. //杈撳嚭锛氭棤
  106. //鍔熻兘鎻忚堪锛歋PI鍒濆鍖栫▼搴?
  107. /*****************************************************************************************/
  108. void CpuInit(void)
  109. {
  110. soc_init();
  111. SpiInit();
  112. cc1101_delay(1500000);
  113. }
  114. //*****************************************************************************************
  115. //鍑芥暟鍚嶏細SpisendByte(INT8U dat)
  116. //杈撳叆锛氬彂閫佺殑鏁版嵁
  117. //杈撳嚭锛氭棤
  118. //鍔熻兘鎻忚堪锛歋PI鍙戦€佷竴涓瓧鑺?
  119. //*****************************************************************************************
  120. INT8U SpiTxRxByte(INT8U dat)
  121. {
  122. INT8U i,temp;
  123. temp = 0;
  124. SCK_L;
  125. for(i=0; i<8; i++)
  126. {
  127. if(dat & 0x80)
  128. {
  129. MOSI_H;
  130. }
  131. else MOSI_L;
  132. dat <<= 1;
  133. SCK_H;
  134. nop_tmp++;
  135. nop_tmp++;
  136. nop_tmp++;
  137. nop_tmp++;
  138. nop_tmp++;
  139. nop_tmp++;
  140. temp <<= 1;
  141. if(MISO)temp++;
  142. SCK_L;
  143. nop_tmp++;
  144. nop_tmp++;
  145. nop_tmp++;
  146. nop_tmp++;
  147. nop_tmp++;
  148. nop_tmp++;
  149. }
  150. return temp;
  151. }
  152. //*****************************************************************************************
  153. //鍑芥暟鍚嶏細void RESET_CC1100(void)
  154. //杈撳叆锛氭棤
  155. //杈撳嚭锛氭棤
  156. //鍔熻兘鎻忚堪锛氬浣岰C1100
  157. //*****************************************************************************************
  158. void RESET_CC1100(void)
  159. {
  160. CSN_L;
  161. while (MISO);
  162. SpiTxRxByte(CCxxx0_SRES);       //鍐欏叆澶嶄綅鍛戒护
  163. while (MISO);
  164. CSN_H;
  165. }
  166. //*****************************************************************************************
  167. //鍑芥暟鍚嶏細void POWER_UP_RESET_CC1100(void)
  168. //杈撳叆锛氭棤
  169. //杈撳嚭锛氭棤
  170. //鍔熻兘鎻忚堪锛氫笂鐢靛浣岰C1100
  171. //*****************************************************************************************
  172. void POWER_UP_RESET_CC1100(void)
  173. {
  174. CSN_H;
  175. halWait(10);
  176. CSN_L;
  177. halWait(10);
  178. CSN_H;
  179. halWait(410);
  180. RESET_CC1100();         //澶嶄綅CC1100
  181. }
  182. //*****************************************************************************************
  183. //鍑芥暟鍚嶏細void halSpiWriteReg(INT8U addr, INT8U value)
  184. //杈撳叆锛氬湴鍧€鍜岄厤缃瓧
  185. //杈撳嚭锛氭棤
  186. //鍔熻兘鎻忚堪锛歋PI鍐欏瘎瀛樺櫒
  187. //*****************************************************************************************
  188. void halSpiWriteReg(INT8U addr, INT8U value)
  189. {
  190. CSN_L;
  191. while (MISO);
  192. SpiTxRxByte(addr);      //鍐欏湴鍧€
  193. SpiTxRxByte(value);     //鍐欏叆閰嶇疆
  194. CSN_H;
  195. }
  196. //*****************************************************************************************
  197. //鍑芥暟鍚嶏細void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
  198. //杈撳叆锛氬湴鍧€锛屽啓鍏ョ紦鍐插尯锛屽啓鍏ヤ釜鏁?
  199. //杈撳嚭锛氭棤
  200. //鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
  201. //*****************************************************************************************
  202. void halSpiWriteBurstReg(INT8U addr, INT8U *buffer, INT8U count)
  203. {
  204. INT8U i, temp;
  205. temp = addr | WRITE_BURST;
  206. CSN_L;
  207. while (MISO);
  208. SpiTxRxByte(temp);
  209. for (i = 0; i < count; i++)
  210. {
  211. SpiTxRxByte(buffer[i]);
  212. }
  213. CSN_H;
  214. }
  215. //*****************************************************************************************
  216. //鍑芥暟鍚嶏細void halSpiStrobe(INT8U strobe)
  217. //杈撳叆锛氬懡浠?
  218. //杈撳嚭锛氭棤
  219. //鍔熻兘鎻忚堪锛歋PI鍐欏懡浠?
  220. //*****************************************************************************************
  221. void halSpiStrobe(INT8U strobe)
  222. {
  223. CSN_L;
  224. while (MISO);
  225. SpiTxRxByte(strobe);        //鍐欏叆鍛戒护
  226. CSN_H;
  227. }
  228. //*****************************************************************************************
  229. //鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
  230. //杈撳叆锛氬湴鍧€
  231. //杈撳嚭锛氳瀵勫瓨鍣ㄧ殑閰嶇疆瀛?
  232. //鍔熻兘鎻忚堪锛歋PI璇诲瘎瀛樺櫒
  233. //*****************************************************************************************
  234. INT8U halSpiReadReg(INT8U addr)
  235. {
  236. INT8U temp, value;
  237. temp = addr|READ_SINGLE;//璇诲瘎瀛樺櫒鍛戒护
  238. CSN_L;
  239. while (MISO);
  240. SpiTxRxByte(temp);
  241. value = SpiTxRxByte(0);
  242. CSN_H;
  243. return value;
  244. }
  245. //*****************************************************************************************
  246. //鍑芥暟鍚嶏細void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
  247. //杈撳叆锛氬湴鍧€锛岃鍑烘暟鎹悗鏆傚瓨鐨勭紦鍐插尯锛岃鍑洪厤缃釜鏁?
  248. //杈撳嚭锛氭棤
  249. //鍔熻兘鎻忚堪锛歋PI杩炵画鍐欓厤缃瘎瀛樺櫒
  250. //*****************************************************************************************
  251. void halSpiReadBurstReg(INT8U addr, INT8U *buffer, INT8U count)
  252. {
  253. INT8U i,temp;
  254. temp = addr | READ_BURST;       //鍐欏叆瑕佽鐨勯厤缃瘎瀛樺櫒鍦板潃鍜岃鍛戒护
  255. CSN_L;
  256. while (MISO);
  257. SpiTxRxByte(temp);
  258. for (i = 0; i < count; i++)
  259. {
  260. buffer[i] = SpiTxRxByte(0);
  261. }
  262. CSN_H;
  263. }
  264. //*****************************************************************************************
  265. //鍑芥暟鍚嶏細INT8U halSpiReadReg(INT8U addr)
  266. //杈撳叆锛氬湴鍧€
  267. //杈撳嚭锛氳鐘舵€佸瘎瀛樺櫒褰撳墠鍊?
  268. //鍔熻兘鎻忚堪锛歋PI璇荤姸鎬佸瘎瀛樺櫒
  269. //*****************************************************************************************
  270. INT8U halSpiReadStatus(INT8U addr)
  271. {
  272. INT8U value,temp;
  273. temp = addr | READ_BURST;       //鍐欏叆瑕佽鐨勭姸鎬佸瘎瀛樺櫒鐨勫湴鍧€鍚屾椂鍐欏叆璇诲懡浠?
  274. CSN_L;
  275. while (MISO);
  276. SpiTxRxByte(temp);
  277. value = SpiTxRxByte(0);
  278. CSN_H;
  279. return value;
  280. }
  281. //*****************************************************************************************
  282. //鍑芥暟鍚嶏細void halRfWriteRfSettings(RF_SETTINGS *pRfSettings)
  283. //杈撳叆锛氭棤
  284. //杈撳嚭锛氭棤
  285. //鍔熻兘鎻忚堪锛氶厤缃瓹C1100鐨勫瘎瀛樺櫒
  286. //*****************************************************************************************
  287. void halRfWriteRfSettings(void)
  288. {
  289. //*******************************此rfSettings配置来自Smart RF***********************************//
  290. //*******************************Low data rate----2.4kbaud**************************************//
  291. //*******************************Carrier frequency-----433.99MHz********************************//
  292. RF_SETTINGS rfSettings = {
  293. 0x06,  // IOCFG0        GDO0 Output Pin Configuration
  294. 0x47,  // FIFOTHR       RX FIFO and TX FIFO Thresholds
  295. 0x05,  // PKTCTRL0      Packet Automation Control
  296. 0x06,  // FSCTRL1       Frequency Synthesizer Control
  297. 0x10,  // FREQ2         Frequency Control Word, High Byte
  298. 0xB1,  // FREQ1         Frequency Control Word, Middle Byte
  299. 0x3B,  // FREQ0         Frequency Control Word, Low Byte
  300. 0xF6,  // MDMCFG4       Modem Configuration
  301. 0x83,  // MDMCFG3       Modem Configuration
  302. 0x13,  // MDMCFG2       Modem Configuration
  303. 0x15,  // DEVIATN       Modem Deviation Setting
  304. 0x18,  // MCSM0         Main Radio Control State Machine Configuration
  305. 0x16,  // FOCCFG        Frequency Offset Compensation Configuration
  306. 0xFB,  // WORCTRL       Wake On Radio Control
  307. 0xE9,  // FSCAL3        Frequency Synthesizer Calibration
  308. 0x2A,  // FSCAL2        Frequency Synthesizer Calibration
  309. 0x00,  // FSCAL1        Frequency Synthesizer Calibration
  310. 0x1F,  // FSCAL0        Frequency Synthesizer Calibration
  311. 0x81,  // TEST2         Various Test Settings
  312. 0x35,  // TEST1         Various Test Settings
  313. 0x09,  // TEST0         Various Test Settings
  314. };
  315. halSpiWriteReg(CCxxx0_IOCFG0,   rfSettings.iocfg0);
  316. halSpiWriteReg(CCxxx0_FIFOTHR,   rfSettings.fifothr);
  317. halSpiWriteReg(CCxxx0_PKTCTRL0,   rfSettings.pktctrl0);
  318. halSpiWriteReg(CCxxx0_FSCTRL1,   rfSettings.fsctrl1);
  319. halSpiWriteReg(CCxxx0_FREQ2,   rfSettings.freq2);
  320. halSpiWriteReg(CCxxx0_FREQ1,   rfSettings.freq1);
  321. halSpiWriteReg(CCxxx0_FREQ0,   rfSettings.freq0);
  322. halSpiWriteReg(CCxxx0_MDMCFG4,   rfSettings.mdmcfg4);
  323. halSpiWriteReg(CCxxx0_MDMCFG3,   rfSettings.mdmcfg3);
  324. halSpiWriteReg(CCxxx0_MDMCFG2,   rfSettings.mdmcfg2);
  325. halSpiWriteReg(CCxxx0_DEVIATN,   rfSettings.deviatn);
  326. halSpiWriteReg(CCxxx0_MCSM0,   rfSettings.mcsm0);
  327. halSpiWriteReg(CCxxx0_FOCCFG,   rfSettings.foccfg);
  328. halSpiWriteReg(CCxxx0_WORCTRL,   rfSettings.worctrl);
  329. halSpiWriteReg(CCxxx0_FSCAL3,   rfSettings.fscal3);
  330. halSpiWriteReg(CCxxx0_FSCAL2,   rfSettings.fscal2);
  331. halSpiWriteReg(CCxxx0_FSCAL1,   rfSettings.fscal1);
  332. halSpiWriteReg(CCxxx0_FSCAL0,   rfSettings.fscal0);
  333. halSpiWriteReg(CCxxx0_TEST2,   rfSettings.test2);
  334. halSpiWriteReg(CCxxx0_TEST1,   rfSettings.test1);
  335. halSpiWriteReg(CCxxx0_TEST0,   rfSettings.test0);
  336. }
  337. //*****************************************************************************************
  338. //鍑芥暟鍚嶏細void halRfSendPacket(INT8U *txBuffer, INT8U size)
  339. //杈撳叆锛氬彂閫佺殑缂撳啿鍖猴紝鍙戦€佹暟鎹釜鏁?
  340. //杈撳嚭锛氭棤
  341. //鍔熻兘鎻忚堪锛欳C1100鍙戦€佷竴缁勬暟鎹?
  342. //*****************************************************************************************
  343. void halRfSendPacket(INT8U *txBuffer, INT8U size)
  344. {
  345. halSpiStrobe(CCxxx0_SIDLE);
  346. halSpiStrobe(CCxxx0_STX);       //杩涘叆鍙戦€佹ā寮忓彂閫佹暟鎹?
  347. halSpiWriteReg(CCxxx0_TXFIFO, size);
  348. halSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size); //鍐欏叆瑕佸彂閫佺殑鏁版嵁
  349. // Wait for GDO0 to be set -> sync transmitted
  350. while (!GDO0);
  351. // Wait for GDO0 to be cleared -> end of packet
  352. while (GDO0);
  353. halSpiStrobe(CCxxx0_SFTX);
  354. halSpiStrobe(CCxxx0_SIDLE);
  355. halSpiStrobe(CCxxx0_SRX);
  356. }
  357. //************************************************************************************************//
  358. //*********************************      鏃犱腑鏂帴鏀跺嚱鏁?     ************************************//
  359. //***********************************************************************************************//
  360. INT8U halRfReceivePacket(INT8U *rxBuffer, INT8U *length)
  361. {
  362. INT8U status[2];
  363. INT8U packetLength;
  364. INT8U i=(*length)*4;  // 鍏蜂綋澶氬皯瑕佹牴鎹甦atarate鍜宭ength鏉ュ喅瀹?
  365. halSpiStrobe(CCxxx0_SIDLE);
  366. halSpiStrobe(CCxxx0_SRX);       //杩涘叆鎺ユ敹鐘舵€?
  367. cc1101_delay(20);
  368. while (GDO0)
  369. {
  370. cc1101_delay(20);
  371. --i;
  372. if(i<1)
  373. return 0;
  374. }
  375. if ((halSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO)) //濡傛灉鎺ョ殑瀛楄妭鏁颁笉涓?
  376. {
  377. packetLength = halSpiReadReg(CCxxx0_RXFIFO);//璇诲嚭绗竴涓瓧鑺傦紝姝ゅ瓧鑺備负璇ュ抚鏁版嵁闀垮害
  378. if (packetLength <= *length)         //濡傛灉鎵€瑕佺殑鏈夋晥鏁版嵁闀垮害灏忎簬绛変簬鎺ユ敹鍒扮殑鏁版嵁鍖呯殑闀垮害
  379. {
  380. halSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength); //璇诲嚭鎵€鏈夋帴鏀跺埌鐨勬暟鎹?
  381. *length = packetLength;             //鎶婃帴鏀舵暟鎹暱搴︾殑淇敼涓哄綋鍓嶆暟鎹殑闀垮害
  382. // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
  383. halSpiReadBurstReg(CCxxx0_RXFIFO, status, 2);   //璇诲嚭CRC鏍¢獙浣?
  384. halSpiStrobe(CCxxx0_SFRX);      //娓呮礂鎺ユ敹缂撳啿鍖?
  385. return (status[1] & CRC_OK);            //濡傛灉鏍¢獙鎴愬姛杩斿洖鎺ユ敹鎴愬姛
  386. }
  387. else
  388. {
  389. *length = packetLength;
  390. halSpiStrobe(CCxxx0_SFRX);      //娓呮礂鎺ユ敹缂撳啿鍖?
  391. return 0;
  392. }
  393. }
  394. else
  395. return 0;
  396. }
  397. static int Init_CC1100(void)
  398. {
  399. INT8U PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};
  400. CpuInit();
  401. POWER_UP_RESET_CC1100();
  402. halRfWriteRfSettings();
  403. halSpiWriteBurstReg(CCxxx0_PATABLE, PaTabel, 8);
  404. return 0;
  405. }
  406. /****************************************************************************************/
  407. #define CC1101_BUFLEN 16
  408. static dev_t cc1101_dev_no = 0;
  409. static volatile int rcv_flag;
  410. /* cc1101设备 */
  411. typedef struct tag_cc1101_dev_t
  412. {
  413. struct cdev cdev;
  414. unsigned char cc1101_buf[CC1101_BUFLEN];
  415. wait_queue_head_t read_wait;
  416. }cc1101_dev_t;
  417. static cc1101_dev_t cc1101_dev;
  418. struct rcv_irq_desc {
  419. int irq;
  420. int pin;
  421. int pin_setting;
  422. char *name;
  423. };
  424. static irqreturn_t cc1101_rcv_interrupt(int irq, void *dev_id)
  425. {
  426. INT8U count = CC1101_BUFLEN;
  427. int ret;
  428. printk("cc1101 handle interrupt!\n");
  429. ret = halRfReceivePacket(cc1101_dev.cc1101_buf, &count);
  430. if (0 != ret)
  431. {
  432. /*
  433. printk("cc1101 receiving .... start\n");
  434. printk("cc1101 receiving .... end\n");
  435. printk("cc1101 receiving %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
  436. */
  437. rcv_flag = 1;
  438. wake_up_interruptible(&cc1101_dev.read_wait);
  439. }
  440. return IRQ_RETVAL(IRQ_HANDLED);
  441. }
  442. static struct rcv_irq_desc cc1101_rcv_irq = {
  443. IRQ_EINT15,
  444. S3C2410_GPG7,
  445. S3C2410_GPG7_EINT15,
  446. "spi_GDO0"};
  447. /*文件打开函数*/
  448. int cc1101_open(struct inode *inode, struct file *filp)
  449. {
  450. int ret;
  451. ret = request_irq(cc1101_rcv_irq.irq, cc1101_rcv_interrupt, IRQ_TYPE_EDGE_FALLING,
  452. cc1101_rcv_irq.name, (void *)&cc1101_rcv_irq);
  453. if (ret)
  454. {
  455. printk("request_irq error!\n");
  456. return -EBUSY;
  457. }
  458. return 0;
  459. }
  460. /*写函数*/
  461. static ssize_t cc1101_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
  462. {
  463. unsigned int count = size;
  464. int ret = 0;
  465. /*分析和获取有效的写长度*/
  466. if (CC1101_BUFLEN != size)
  467. {
  468. printk("cc1101 write wrong len:%d\n", size);
  469. return -ENOMEM;
  470. }
  471. /*用户空间->内核空间*/
  472. if (copy_from_user(cc1101_dev.cc1101_buf, buf, count))
  473. ret =  - EFAULT;
  474. else
  475. {
  476. ret = count;
  477. //printk("kernel-space: cc1101 written %d bytes(s):%s\n", count, cc1101_dev.cc1101_buf);
  478. }
  479. /* CC1101硬件发送 */
  480. //printk("kernel-space: cc1101 sending .... start\n");
  481. halRfSendPacket(cc1101_dev.cc1101_buf, count);
  482. //printk("kernel-space: cc1101 sending .... end\n");
  483. return ret;
  484. }
  485. /* 读函数 */
  486. static ssize_t cc1101_waitqueue_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
  487. {
  488. unsigned int count = size;
  489. int ret = 0;
  490. DECLARE_WAITQUEUE(wait, current);
  491. if (CC1101_BUFLEN != count)
  492. {
  493. printk("kernel-space: cc1101 read wrong len:%d\n", count);
  494. return -ENOMEM;
  495. }
  496. add_wait_queue(&cc1101_dev.read_wait, &wait);
  497. if (0 == rcv_flag)
  498. {
  499. if (filp->f_flags & O_NONBLOCK)
  500. {
  501. ret = -EAGAIN;
  502. goto out;
  503. }
  504. __set_current_state(TASK_INTERRUPTIBLE);
  505. schedule();
  506. if (signal_pending(current))
  507. {
  508. ret =  - ERESTARTSYS;
  509. goto out;
  510. }
  511. }
  512. /* 内核空间->用户空间 */
  513. copy_to_user(buf, cc1101_dev.cc1101_buf, count);
  514. ret = count;
  515. out:
  516. remove_wait_queue(&cc1101_dev.read_wait, &wait);
  517. set_current_state(TASK_RUNNING);
  518. rcv_flag = 0;
  519. return ret;
  520. }
  521. /* poll函数 */
  522. static unsigned int cc1101_poll(struct file *filp, poll_table *wait)
  523. {
  524. unsigned int mask = 0;
  525. poll_wait(filp, &cc1101_dev.read_wait, wait);
  526. if (1 == rcv_flag)
  527. {
  528. mask |= POLLIN | POLLRDNORM;
  529. printk("kernel-space: cc1101_poll rcv_flag = 1!\n");
  530. }
  531. return mask;
  532. }
  533. static int cc1101_close(struct inode *inode, struct file *file)
  534. {
  535. free_irq(cc1101_rcv_irq.irq, (void *)&cc1101_rcv_irq);
  536. printk("kernel-space: cc1101_close!\n");
  537. return 0;
  538. }
  539. struct file_operations cc1101_fops =
  540. {
  541. .owner = THIS_MODULE,
  542. .open = cc1101_open,
  543. .release = cc1101_close,
  544. .write = cc1101_write,
  545. .read = cc1101_waitqueue_read,
  546. .poll = cc1101_poll,
  547. };
  548. /*初始化并注册cdev*/
  549. static int cc1101_setup_cdev(void)
  550. {
  551. int err;
  552. cdev_init(&cc1101_dev.cdev, &cc1101_fops);
  553. cc1101_dev.cdev.owner = THIS_MODULE;
  554. cc1101_dev.cdev.ops = &cc1101_fops;
  555. err = cdev_add(&cc1101_dev.cdev, cc1101_dev_no, 1);
  556. if (err)
  557. printk("cc1101 cc1101_setup_cdev error!");
  558. return err;
  559. }
  560. static int __init cc1101_init(void)
  561. {
  562. int ret = 0;
  563. ret = Init_CC1100();
  564. if (0 != ret)
  565. goto init_fail;
  566. ret = alloc_chrdev_region(&cc1101_dev_no, 0, 1, "cc1101");
  567. if (0 < ret)
  568. goto init_fail;
  569. init_waitqueue_head(&cc1101_dev.read_wait);
  570. ret = cc1101_setup_cdev();
  571. if (0 != ret)
  572. {
  573. unregister_chrdev_region(cc1101_dev_no, 1);
  574. goto init_fail;
  575. }
  576. printk("cc1101 init success!\n");
  577. return 0;
  578. init_fail:
  579. printk("cc1101 init failed!\n");
  580. return ret;
  581. }
  582. static void  __exit cc1101_exit(void)
  583. {
  584. unregister_chrdev_region(cc1101_dev_no, 1);
  585. cdev_del(&cc1101_dev.cdev);
  586. printk("cc1101 exit success!\n");
  587. }
  588. module_init(cc1101_init);
  589. module_exit(cc1101_exit);
  590. MODULE_LICENSE("GPL");
  591. MODULE_AUTHOR("forsakening-hdu");
  592. MODULE_DESCRIPTION("cc1101 control for EmbedSky TQ2440 Board");
时间: 2024-11-06 07:30:00

linux 驱动cc1101的相关文章

Linux代码的重用与强行卸载Linux驱动

(一)Linux代码的重用 重用=静态重用(将要重用的代码放到其他的文件的头文件中声明)+动态重用(使用另外一个Linux驱动中的资源,例如函数.变量.宏等) 1.编译是由多个文件组成的Linux驱动(静态重用) 对于复杂的Linux驱动,需要使用多个源代码文件存放不同的功能代码,这样做有利于代码分类和管理,那么就不得不编译多个源代码文件,最终生成.ko文件或编译进Linux内核 下面,就介绍将3个.c文件分别编译为3个.o文件,并将这3个.o文件链接(link)成一个.ko文件——静态重用 假

第六章——使用实例来理解Linux驱动开发及心得

在这一章中主要介绍了一个Linux驱动程序,以实战的方式向我们介绍了一个Linux驱动程序的例子. Linux驱动的工作和访问方式是Linux的亮点之一,同时受到了业界的广泛好评. Linux系统 将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目录中.这种 设计理念使得与Linux驱动进行交互就像与普通文件进行交互一样容易.当然,也比访问LinuxAPI 更容易. 由于大多数Linux驱动都有与其对应的设备文件, 因此与Linux驱动交换数据就变成了与 设备文件交

Linux驱动开发盲点笔记1

1. vim中在找到搜索目标后,使用n与N进行定位查找 2. vim中使用gg到最好第一行,使用xxxG到某一行,否则G直接到最后一行: 3. ln -s 产生的链接文件最终指向的目标文件src 新产生的当前软链接文件dst. ln -s project(磁盘上实际存在的文件或者目录) a.lnk ln -s src dst(新产生的文件dst,dst链接到src) symlink功能类似 4 tar -czvf 最终生产的tar打包好的文件 待打包的文件或者文件夹 tar czvf a.tar

常见 wifi热点的linux 驱动

小度Wifi.360Wifi Windows.linux驱动 小度wifi什么的就是一个无线网卡,当然可以自由使用,然官方却说不支持无限网卡功能… 现提供Windows平台和linux平台的驱动安装方法. Windows 驱动下载:http://pan.baidu.com/s/1GcFF1 Linux 使用lsusb命令可以获取USB设备ID.小度wifi为2955:0001或2955:1001 360WIFI2为148F:760B 二者均使用Mediatek Ralink MT7601芯片,都

浅析Linux驱动模型中的底层数据结构kobject和kset

1.kobject Linux内核用kobject来表示一个内核对象.它和Sysfs文件系统联系密切,在内核中注册到系统中的每个kobject对象在sysfs文件系统中对对应着一个文件目录.kobject数据结构通常的用法是嵌入到其对他的数据结构中(即容器,比如cdev结构),用于实现内核对该类数据结构对象的管理.这些数据结构(容器)通过kobject连接起来,形成了一个树状结构. 它在源码中的定义为: /*<include/linux/kobject.h>*/ struct kobject

Linux驱动经典面试题目

1.  linux驱动分类 2.  信号量与自旋锁 3.  platform总线设备及总线设备如何编写 4.  kmalloc和vmalloc的区别 5.  module_init的级别 6.  添加驱动 7.  IIC原理,总线框架,设备编写方法,i2c_msg 8.  kernel panic 9.  USB总线,USB传输种类,urb等 10.android boot 流程 11.android init解析init.rcLinux驱动经典面试题目,布布扣,bubuko.com

几个Linux驱动面试题目

这几天面试几个想做安卓Linux驱动的,总体感觉上驱动基础还是比较薄弱,大部分情况是虽然做过驱动,但是基本上都是采用内核现成的,或者是开发板上已经有的,单独写过模块驱动很少,驱动机制理解不是很透彻.以下是几个随口问过的基础问题,供参考. 1.字符型驱动设备你是怎么创建设备文件的,就是/dev/下面的设备文件,供上层应用程序打开使用的? 2.写一个中断服务需要注意哪些?如果中断产生之后要做比较多的事情你是怎么做的? 3.自旋锁和信号量在互斥使用时需要注意哪些?在中断服务程序里面的互斥是使用自旋锁还

【Linux 驱动】设备驱动程序再理解

学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下.学习设备驱动编程也有一段时间了,也写过了几个驱动程序,因此有对设备驱动程序有了一些新的理解和认识,总结一下. ★什么是驱动程序 刚开始学习设备驱动程序的时候,产生了许多的问题.什么是驱动程序?驱动程序是干嘛的?它是如何工作的?它又是如何跟操作系统联系起来的?一系列的问题,现在有些地方还是不一定清楚,但是相比起刚开始的那个阶段,感觉自己还是清楚了很多. 设备驱动程序说白了(实质)就是为应用程

【Linux驱动】TQ2440 LED驱动程序

★总体介绍 LED驱动程序主要实现了TQ2440开发板上的4个LED灯的硬件驱动,实现了对引脚GPIOB5.GPIOB6.GPIOB7.GPIOB8的高低电平设置(common-smdk.c中已经实现了对引脚的配置),利用测试程序调用该驱动程序,通过命令控制LED灯的亮灭. ★详细介绍 1.驱动程序代码:My_led.c #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #