Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.22 KB | None | 0 0
  1. //
  2. // rfm12 ASK driver - this driver module adds rfm12 ASK support to the
  3. //                    linux kernel
  4. //
  5. // Copyright (C) 2010 Mirko Vogt <dev@nanl.de>
  6. //
  7. // This program is free software; you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License as published by
  9. // the Free Software Foundation; either version 2 of the License, or
  10. // (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License
  18. // along with this program; if not, write to the Free Software
  19. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. // //
  21.  
  22.  
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/spi/spi.h>
  26. #include <linux/fs.h>
  27. #include <asm/uaccess.h>
  28.  
  29. #define DEVICE_NAME "rfm12_ask"
  30.  
  31. #define DATA_MAX 512
  32.  
  33. //#define SPI 1
  34. #define DEBUG 1
  35.  
  36. #ifdef DEBUG
  37. //#  define DBG ( x ) printk (KERN_ALERT x)
  38. #  define DBG_FMT(fmt, ...) printk(KERN_ALERT "%d <%s> : " fmt, __LINE__, __FUNCTION__, __VA_ARGS__)
  39. #  define DBG(str) printk(KERN_ALERT "%d <%s> : " str, __LINE__, __FUNCTION__)
  40. #  define MARK() printk(KERN_ALERT "%d <%s>\n", __LINE__, __FUNCTION__)
  41. #else
  42. #  define DBG_FMT(fmt, ...)
  43. #  define DBG(str)
  44. #  define MARK()
  45. #endif
  46.  
  47. int ask_2272_1527_pulse_duty_factor[4]={13,5,7,11};
  48.  
  49. struct spi_device *spi;
  50.  
  51. u16 word;
  52.  
  53. struct packet {
  54.     unsigned int duration;
  55.     unsigned int count;
  56.     u8 data[DATA_MAX]; // payload
  57. };
  58.  
  59. //int len_body = 0; // length of payload - if no we expect a header is going to be received
  60.  
  61. static int device_open(struct inode *, struct file *);
  62. static int device_release(struct inode *, struct file *);
  63. static ssize_t device_read(struct file *, char *, size_t, loff_t *);
  64. static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
  65.  
  66. static void rfm12_tx_on(void);
  67. static void rfm12_tx_off(void);
  68.  
  69. void
  70. rfm12_ask_encode_tribit(int *code, int append, int byte, int cnt)
  71. {
  72.     int i;
  73.     for (i=0;i<cnt;i++)
  74.     {
  75.         if (byte & (1<<(cnt-i-1))) {
  76.             code[append+(i*2)]=ask_2272_1527_pulse_duty_factor[0];
  77.             code[append+(i*2)+1]=ask_2272_1527_pulse_duty_factor[1];
  78.         } else {
  79.             code[append+(i*2)]=ask_2272_1527_pulse_duty_factor[2];
  80.             code[append+(i*2)+1]=ask_2272_1527_pulse_duty_factor[3];
  81.         }
  82.     }
  83. }
  84.  
  85. int rfm12_ask_modulate(struct packet *packet)
  86. {
  87.     unsigned int duration = packet->duration;
  88.     unsigned int count = packet->count;
  89.     u8 *data = packet->data;
  90.     DBG_FMT("got packet:\n  duration: %i\n  count: %i\n  data: %s\n", duration, count, data);
  91.     int i;
  92.     for(;count>0;count--) {
  93.         for(i=0;data[i]!='\0';i++) {
  94.             unsigned int us = duration;
  95.             switch(data[i]) {
  96.                 case '1':
  97.                     DBG("switch on TX\n");
  98.                     rfm12_tx_on();
  99.                     for(;us>0;us--)
  100.                         udelay(1);
  101.                     break;
  102.                 case '0':
  103.                     DBG("switch off TX\n");
  104.                     rfm12_tx_off();
  105.                     for(;us>0;us--)
  106.                         udelay(1);
  107.                     break;
  108.                default:
  109.                     DBG_FMT("MOEP! character <%c> is invalid!\n", data[i]);
  110.                     return -EINVAL;
  111.             }
  112.         }
  113.     }
  114.     return 0;
  115. }
  116.  
  117. void
  118. rfm12_ask_trigger(int level, int us)
  119. {
  120.     if (level)
  121.     {
  122.         word = 0x8200|(1<<5)|(1<<4)|(1<<3);
  123.         spi_write(spi, (const u8 *)&word, 2);
  124.         for(;us>0;us--)
  125.             udelay(1);
  126.     }
  127.     else
  128.     {
  129.         word = 0x8208;
  130.         spi_write(spi, (const u8 *)&word, 2);
  131.         for(;us>0;us--)
  132.             udelay(1);
  133.     }
  134. }
  135.  
  136. // inline to avoid unneeded jumps
  137. inline static void rfm12_tx_on(void)
  138. {
  139. #ifdef SPI
  140.     word = 0x8200|(1<<5)|(1<<4)|(1<<3);
  141.     spi_write(spi, (const u8 *)&word, 2);
  142. #endif
  143. }
  144.  
  145. // inline to avoid unneeded jumps
  146. inline static void rfm12_tx_off(void)
  147. {
  148. #ifdef SPI
  149.     word = 0x8208;
  150.     spi_write(spi, (const u8 *)&word, 2);
  151. #endif
  152. }
  153.  
  154. static void _write_spi(u8 _word)
  155. {
  156. #ifdef SPI
  157.     word = _word;
  158.     spi_write(spi, (const u8 *)&word, 2);
  159. #endif
  160. }
  161.  
  162. void
  163. rfm12_ask_2272_send(int *command, int delay, int cnt)
  164. {
  165.     int code[49];
  166.  
  167.     int i;
  168.     printk(KERN_ALERT "encoding\n");
  169.     for(i=0;i<3;i++)
  170.     {
  171.         rfm12_ask_encode_tribit(code, i*16, command[i], 8);
  172.     }
  173.     code[48]=7; //sync
  174.     word = 0x8200|(1<<5)|(1<<4)|(1<<3);
  175.     printk(KERN_ALERT "??\n");
  176.     spi_write(spi, (const u8 *)&word, 2);     // 2. PwrMngt TX on
  177.     int ii;
  178.     for(ii=cnt;ii>0;ii--)                             // Sequenz cnt send
  179.     {
  180.         int rfm12_trigger_level=0;
  181.         int i;
  182.         for(i=0;i<49;i++)
  183.         {
  184.         printk(KERN_ALERT "running trigger\n");
  185.             rfm12_ask_trigger(rfm12_trigger_level^=1,code[i]*delay);
  186.         }
  187.         printk(KERN_ALERT "running trigger (2)\n");
  188.         rfm12_ask_trigger(0,24*delay);
  189.     }
  190.     word = 0x8208;
  191.     printk(KERN_ALERT "set <0x8208>\n");
  192.     spi_write(spi, (const u8 *)&word, 2);
  193. }
  194.  
  195. #define RFM12BAND(freq)    (freq<800000?0x80D7:0x80E7)
  196.  
  197. static int __devinit rfm12_probe(struct spi_device *spi_)
  198. {
  199.     DBG("probing\n");
  200.     spi = spi_;
  201.     DBG("setting mode\n");
  202.     spi->mode = SPI_MODE_0;
  203.     DBG("setting word size\n");
  204.     spi->bits_per_word = 16;
  205.     DBG("setup spi device\n");
  206.     spi_setup(spi);
  207.  
  208.     //word = 0x0000;
  209.     //spi_write(spi, (const u8 *)&word, 2);
  210.  
  211.     word = 0x0000;
  212.     MARK();
  213.     spi_write(spi, (const u8 *)&word, 2);
  214.     spi_read(spi, (u8 *)&word, 2);
  215.     MARK();
  216.  
  217.     word = 0xC0E0;
  218.     MARK();
  219.     spi_write(spi, (const u8 *)&word, 2);        /* AVR CLK: 10MHz */
  220.     word = RFM12BAND(433920);
  221.     MARK();
  222.     spi_write(spi, (const u8 *)&word, 2);    /* Select BAND, Enable FIFO */
  223.     word = 0xC2AB;
  224.     MARK();
  225.     spi_write(spi, (const u8 *)&word, 2);        /* Data Filter: internal */
  226.     word = 0xCA81;
  227.     MARK();
  228.     spi_write(spi, (const u8 *)&word, 2);        /* Set FIFO mode */
  229.     word = 0xE000;
  230.     MARK();
  231.     spi_write(spi, (const u8 *)&word, 2);        /* disable wakeuptimer */
  232.     word = 0xC800;
  233.     MARK();
  234.     spi_write(spi, (const u8 *)&word, 2);        /* disable low duty cycle */
  235.     word = 0xC4F7;
  236.     MARK();
  237.     spi_write(spi, (const u8 *)&word, 2);        /* AFC settings: autotuning: -10kHz...+7,5kHz */
  238.  
  239.     int command[3];
  240.     command[0] = 0;
  241.     command[1] = 5;
  242.     command[2] = 81;
  243.     DBG("sending (0,5,81), 76, 10\n");
  244.     rfm12_ask_2272_send(command, 76, 10);
  245.     DBG("finished\n");
  246.  
  247.     return 0;
  248. }
  249.  
  250. static struct spi_driver rfm12_driver = {
  251.     .driver = {
  252.         .name = "rfm12",
  253.         .owner = THIS_MODULE,
  254.     },
  255.     .probe = rfm12_probe,
  256. };
  257.  
  258.  
  259. static int device_open(struct inode *inode, struct file *file)
  260. {
  261.     DBG("device opened\n");
  262.     return 0;
  263. }
  264.  
  265. static ssize_t device_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
  266. {
  267.     DBG("device read attempt\n");
  268.     return -EINVAL;
  269. }
  270.  
  271. static ssize_t device_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
  272. {
  273.     DBG("device write attempt\n");
  274.     DBG_FMT("length: %i\n", length);
  275.     //struct packet _x;
  276.     //struct packet *foo = &_x;
  277.     struct packet foo;
  278.     DBG_FMT("size should be greater than %i but less than %i - it is: %i\n", sizeof(struct packet) - DATA_MAX, sizeof(struct packet), length);
  279.     if ((length > sizeof(struct packet)) || (length <= (sizeof(struct packet) - DATA_MAX))) // too much or no payload
  280.         return -EINVAL;
  281.     DBG_FMT("allocated memory variable is assigned to: %i", sizeof(foo));
  282.     if (copy_from_user(&foo, buffer, length))
  283.         return -EFAULT;
  284.     foo.data[length - (sizeof(struct packet) - DATA_MAX)] = '\0'; // set 0-Byte to end of string
  285.     DBG_FMT("  header :: duration: %i, count: %i\n", foo.duration, foo.count);
  286.     DBG_FMT("  payload :: as string: < %s >\n", foo.data);
  287.  
  288.     //if (!rfm12_ask_modulate(foo))
  289.     //    return -EINVAL;
  290.  
  291.     DBG_FMT("return: %i\n", length);
  292.     return length;
  293. }
  294.  
  295. static int device_release(struct inode *inode, struct file *file)
  296. {
  297.     DBG("device released\n");
  298.     return 0;
  299. }
  300.  
  301. struct file_operations fops = {
  302.     .read = device_read,
  303.     .write = device_write,
  304.     .open = device_open,
  305.     .release = device_release
  306. };
  307.  
  308. int init_module(void)
  309. {
  310.     DBG("init module\n");
  311.     int major_nr = register_chrdev(0, DEVICE_NAME, &fops);
  312.  
  313.     if (major_nr < 0) {
  314.         DBG_FMT("Registering char device failed with %d\n", major_nr);
  315.         return major_nr;
  316.     }
  317.     DBG_FMT("device major number is: %i\n", major_nr);
  318.  
  319. #ifdef SPI
  320.     DBG_FMT("register spi driver\n");
  321.     int res_spi_register_driver = spi_register_driver(&rfm12_driver);
  322.     //int res_setup_sysfs = setup_sysfs();
  323.     //return res_spi_register_driver | res_setup_sysfs;
  324.     return res_spi_register_driver;
  325. #endif
  326.     return 0;
  327. }
  328.  
  329. void cleanup_module(void)
  330. {
  331. #ifdef SPI
  332.     spi_unregister_driver(&rfm12_driver);
  333. #endif
  334. }
  335.  
  336. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement