Advertisement
Guest User

Untitled

a guest
Mar 1st, 2013
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.76 KB | None | 0 0
  1. #include <linux/kernel.h> /* Для printk() и т.д. */
  2. #include <linux/module.h> /* Эта частичка древней магии, которая оживляет модули */
  3. #include <linux/init.h> /* Определения макросов */
  4. #include <linux/fs.h>
  5. #include <asm/uaccess.h> /* put_user */
  6. #include <asm/io.h>
  7. //#include <asm/system.h>
  8. #include <linux/ioport.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/slab.h>
  11.  
  12. #include "mx53.h"
  13. #include "spislave.h"
  14.  
  15. // Ниже мы задаём информацию о модуле, которую можно будет увидеть с помощью Modinfo
  16. MODULE_LICENSE( "GPL" );
  17. MODULE_AUTHOR( "" );
  18. MODULE_DESCRIPTION( "Spi slave driver for imx53" );
  19. MODULE_SUPPORTED_DEVICE( "spi" ); /* /dev/testdevice */
  20.  
  21. #define IRQ_NAME "spislave_irq"
  22. #define IRQ_NUMB  37 // ECSPI-2 irq number  
  23.  
  24. #define SUCCESS 0
  25. #define DEVICE_NAME "spislave" /* Имя нашего устройства */
  26.  
  27. #define INPUT_BUFFER_SIZE  (1*1024*1024)
  28. #define BYTES_IN_FIFO_IRQ_OCCURS    24 // кол-во байт в фифо когда генерится прерывание (макс 32)
  29.  
  30. //#define DEBUG_OUTPUT_ENABLED
  31.  
  32.  
  33. struct {
  34.     char data [INPUT_BUFFER_SIZE];
  35.     int start;
  36.     int end;
  37.     } inputBuffer;
  38.  
  39. static int maxRxFifoLoad;
  40. static int maxBufferLoad;
  41. static int rxoverflowedCount;
  42. static char locked;
  43.  
  44.  
  45. // Поддерживаемые нашим устройством операции
  46. static int device_open( struct inode *, struct file * );
  47. static int device_release( struct inode *, struct file * );
  48. static ssize_t device_read( struct file *, char *, size_t, loff_t * );
  49. static ssize_t device_write( struct file *, const char *, size_t, loff_t * );
  50. static int region_size = 256;
  51.  
  52. // Глобальные переменные, объявлены как static, воизбежание конфликтов имен.
  53. static int major_number; /* Старший номер устройства нашего драйвера */
  54. static int is_device_open = 0; /* Используется ли девайс ? */
  55. static void *spi_base;
  56. static void *gpio2_base;
  57.  
  58. //-------------------------------------------------------------------------------------
  59. // Прописываем обработчики операций на устройством
  60. static struct file_operations fops =
  61.  {
  62.   .read = device_read,
  63.   .write = device_write,
  64.   .open = device_open,
  65.   .release = device_release
  66.  };
  67.  
  68.  
  69.  
  70. //-------------------------------------------------------------------------------------
  71. //---------------------------- SPI STUFF    -------------------------------------------
  72. //-------------------------------------------------------------------------------------
  73. //-------------------------------------------------------------------------------------
  74.  
  75.  
  76. static void ResetInputBuffer(void)
  77. {
  78. inputBuffer.start=0;
  79. inputBuffer.end=0;
  80. }
  81.  
  82.  
  83.  
  84. //-------------------------------------------------------------------------------------
  85. static void ConfigureSpi(void)
  86. {
  87.  
  88.     // ------- CONREG -----------
  89.     // CONREG: 19-18 : 00=channel 0 select (SS0),
  90.     //         7-4 : CHANNEL MODE 0-slave/1-master, [3]-channel 3... [0]-channel 0
  91.     //         3: SMC - immediately starts SPI burst when data is written to TXFIFO
  92.     *(int*)(spi_base+ECSPI2_CONREG) = 0x00 ; // enable bit OFF, to reset block
  93.     *(int*)(spi_base+ECSPI2_CONREG) |= (1<<3) | (0x07<<20); // | (0x08<<20); // channel 0 slave , SMC enabled, 8 bits SPI burst
  94.  
  95.     // ------- CONFIGREG -----------
  96.     // *(int*)(spi_base+ECSPI2_CONFIGREG) = 0x01 ;   // согласно картинке Меньшова нам нужен режим POL=0 PHA=1
  97.     *(int*)(spi_base+ECSPI2_CONFIGREG) = 0x00;   // согласно картинке Меньшова нам нужен режим POL=0 PHA=0
  98.    
  99.     // ------- INTREG -----------
  100.     *(int*)(spi_base+ECSPI2_INTREG) = (1<<4) ; // 4: rx fifo data request enable (rxfifo > rx threshold)
  101.    
  102.     // ------- DMAREG -----------
  103.     *(int*)(spi_base+ECSPI2_DMAREG) = (BYTES_IN_FIFO_IRQ_OCCURS<<16); // = (1<<23);   // DMAREG: 21-16: rx threshold
  104.     // DMAREG:
  105.     //   23-RXDEN-RXFIFO DMA request enable
  106.    
  107.     // ------- PERIODREG -----------
  108. // PERIODREG only for master:
  109. // << PERIODREG SKIPPED >>
  110. //    15 - CSRC : 0-Spi clock, 1- Low freq ref clk 32.768Khz   
  111.  
  112.     // ------- TESTREG -----------
  113.     // TESTREG:
  114.     //   31- LBC: 1- loopback enabled - receiver is connected to transmitter
  115.     *(int*)(spi_base+ECSPI2_TESTREG) = 0;
  116.  
  117.     *(int*)(spi_base+ECSPI2_CONREG) |= 0x01; // enable bit ON
  118.  
  119.  
  120. //----------- end of SPI configure ------------------
  121. }
  122.  
  123. //-------------------------------------------------------------------------------------
  124. // Функция загрузки модуля. Входная точка. Можем считать что это наш main()
  125. static int __init spislave_init( void )
  126. {
  127. struct resource *res;
  128.  
  129. printk( KERN_ALERT "spi driver: configuring ECSPI-2...\n" );
  130. res= request_mem_region(ECSPI2_BASE, region_size, "spi");
  131. spi_base = ioremap_nocache(ECSPI2_BASE, region_size);
  132.  
  133. res= request_mem_region(GPIO2_BASE, region_size, "gpio2");
  134. gpio2_base= ioremap_nocache(GPIO2_BASE, region_size);
  135.  
  136. *(int*)(gpio2_base+GPIO_GDIR) |= (1<<24);   // 1 means output
  137.  
  138. ConfigureSpi();
  139.    
  140. printk( KERN_ALERT "spi driver: spislave driver loaded!\n" );
  141.  
  142.  
  143.  // Регистрируем устройсво и получаем старший номер устройства
  144. major_number = register_chrdev( 0, DEVICE_NAME, &fops );
  145.  
  146. if ( major_number < 0 )
  147.     {
  148.     printk( "spi driver: Registering the character device failed with %d\n", major_number );
  149.     return major_number;
  150.     }
  151.  
  152.  // Сообщаем присвоенный нам старший номер устройства
  153. printk( "spi driver: spislave module is loaded!\n" );
  154.  
  155. printk( "spi driver: Please, create a dev file with 'mknod /dev/spislave c %d 0'.\n", major_number );
  156.  
  157. return SUCCESS;
  158. }
  159.  
  160. //-------------------------------------------------------------------------------------
  161. // Функция выгрузки модуля
  162. static void __exit spislave_exit( void )
  163. {
  164.  // Освобождаем устройство
  165.  
  166.  iounmap(spi_base);
  167.  release_mem_region(ECSPI2_BASE, region_size);
  168.  
  169.  unregister_chrdev( major_number, DEVICE_NAME );
  170.  
  171.  printk( KERN_ALERT "spi driver: spislave module is unloaded!\n" );
  172. }
  173. //-------------------------------------------------------------------------------------
  174. // Указываем наши функции загрузки и выгрузки
  175. module_init( spislave_init );
  176. module_exit( spislave_exit );
  177.  
  178. static void CheckMaxRxFifoLoad(int load)
  179. {
  180. if (load> maxRxFifoLoad)
  181.     {
  182.     maxRxFifoLoad=load;
  183.     printk (KERN_ALERT "max rx fifo load=%d\n", maxRxFifoLoad);
  184.     if (maxRxFifoLoad==64)
  185.         {
  186.         printk (KERN_ALERT "rx fifo MAXIMUM REACHED. cleared.\n");
  187.         maxRxFifoLoad=0;
  188.         }
  189.     }
  190. }
  191.    
  192.  
  193.  
  194.  
  195. //-------------------------------------------------------------------------------------
  196. static irqreturn_t irq_handler(int irq, void *dummy, struct pt_regs * regs)
  197. {
  198. int testReg;
  199. int rxFifoCounter;
  200. int rxData;
  201. int counter;
  202. *(int*)(gpio2_base+GPIO_DR) |= (1<<24);
  203.  
  204. // экспериментально выяснил, что irq_handler может возникать во время операции read, т.е.
  205. // read не являются блокирующим для прерывания (по идее так и должно быть, однако были в свое время подозрения).
  206.  
  207. //printk(KERN_ALERT "spi IRQ: Interrupt handler executed!\n");
  208.  
  209. counter = 256; // число байт которые можем схавать за раз в одном прерывании. это по сути защита от зависонов.
  210.         //теоретически может быть
  211.             //   больше чем весь FIFO, т.к. пока сидим и хаваем данные тут могут прийти еще данные в FIFO
  212.        
  213. //printk(KERN_ALERT "spi IRQ: %d bytes in buffer\n", rxFifoCounter);
  214.  
  215. testReg = *(int*)(spi_base+ECSPI2_TESTREG);
  216. rxFifoCounter = ((testReg>>8) & 0x7F);// only 7 bits used
  217. #if defined(DEBUG_OUTPUT_ENABLED)
  218. CheckMaxRxFifoLoad(rxFifoCounter);
  219. #endif
  220.  
  221.  
  222. while (rxFifoCounter>0)
  223.     {
  224.     rxData = *(int*)(spi_base+ECSPI2_RXDATA);
  225. locked=1; // lock inputBuffer  
  226.     inputBuffer.data[inputBuffer.end] = rxData & 0xFF;
  227.     inputBuffer.end = (inputBuffer.end+1) % INPUT_BUFFER_SIZE;
  228.    
  229. locked=0; // unlock inputBuffer
  230.     testReg = *(int*)(spi_base+ECSPI2_TESTREG);
  231.     rxFifoCounter = ((testReg>>8)  & 0x7F);// only 7 bits used  
  232. #if defined(DEBUG_OUTPUT_ENABLED)
  233.     CheckMaxRxFifoLoad(rxFifoCounter);
  234. #endif
  235.     if (!(counter--))  // защита от зависонов
  236.         break;
  237.     }
  238.  
  239. //*(int*)(spi_base+ECSPI2_INTREG) = 0; //debugging
  240.  
  241. *(int*)(gpio2_base+GPIO_DR) &= ~(1<<24);
  242. return IRQ_HANDLED;
  243. }
  244. //-------------------------------------------------------------------------------------
  245. void ResetMaxRxFifoLoad(void)
  246. {
  247. maxRxFifoLoad=0;
  248. maxBufferLoad=0 ;
  249. rxoverflowedCount=0;
  250. #if defined(DEBUG_OUTPUT_ENABLED)
  251. printk (KERN_ALERT "max rx fifo reset\n");
  252. #endif
  253. }
  254. //-------------------------------------------------------------------------------------
  255.  
  256.  
  257. static int device_open( struct inode *inode, struct file *file )
  258. {
  259. int status = 0;
  260.  
  261. locked=0;
  262. if ( is_device_open )
  263.   return -EBUSY;
  264.  
  265. ResetInputBuffer();
  266.  
  267. printk("spi driver: Requesting interrupt\n");
  268. status = request_irq(IRQ_NUMB, irq_handler,0,IRQ_NAME, NULL);
  269. //enable_irq (IRQ_NUMB);
  270. if (status == 0)
  271.     {
  272.     printk("spi driver: spi IRQ request successful!\n");
  273.     }
  274. else
  275.     {
  276.     printk("spi driver: spi IRQ request failed!\n");
  277.     return status;
  278.     }
  279.  
  280. ResetMaxRxFifoLoad();
  281.  
  282.  is_device_open++;
  283.  
  284.  return SUCCESS;
  285. }
  286. //-------------------------------------------------------------------------------------
  287. static int device_release( struct inode *inode, struct file *file )
  288. {
  289. is_device_open--;
  290. printk ("spi driver: spi irq freed\n");
  291. free_irq(IRQ_NUMB, NULL);
  292. ResetMaxRxFifoLoad();
  293.  
  294. return SUCCESS;
  295. }
  296. //-------------------------------------------------------------------------------------
  297. static ssize_t
  298.  
  299. device_write( struct file *filp, const char *buff, size_t len, loff_t * off )
  300. {
  301.  printk( "spi driver: Sorry, this operation isn't supported.\n" );
  302.  return -EINVAL;
  303. }
  304.  
  305. //-------------------------------------------------------------------------------------
  306. static ssize_t device_read( struct file *filp, /* include/linux/fs.h */
  307.        char *buffer, /* buffer */
  308.        size_t length, /* buffer length */
  309.        loff_t * offset )
  310. {
  311. #define MAX_FAILED_OPS   128
  312. int byte_read = 0;
  313. char rx;
  314. int curBufferLoad = (inputBuffer.end>=inputBuffer.start)? (inputBuffer.end-inputBuffer.start) : (INPUT_BUFFER_SIZE-inputBuffer.start + inputBuffer.start);
  315. int failedOps=0;
  316.  
  317. #if defined(DEBUG_OUTPUT_ENABLED)
  318. int rxoverflowed = *(int*)(spi_base+ECSPI2_STATREG) & (1<<6);
  319. if (rxoverflowed)
  320.     {
  321.     *(int*)(spi_base+ECSPI2_STATREG) |= (1<<6) ; // writing to 1 to this bit to clear overflow flag
  322.     rxoverflowedCount++;
  323.     //if (rxoverflowedCount % 5 ==0)
  324.         printk (KERN_ERR "overflow count = %d\n", rxoverflowedCount);
  325.     }
  326. #endif
  327.  
  328. while ( length )
  329.     {
  330.     // need to avoid processing during active interrupt handler process
  331.     // check if inputBuffer is unlocked
  332.     if (locked)
  333.         {
  334.         failedOps++;
  335.         if (failedOps>MAX_FAILED_OPS)
  336.             break;
  337.         else
  338.             continue;
  339.         }
  340.     if (inputBuffer.start==inputBuffer.end)
  341.         break;
  342.  
  343.     rx = inputBuffer.data[inputBuffer.start];
  344.     inputBuffer.start = (inputBuffer.start+1) % INPUT_BUFFER_SIZE;
  345.  
  346.     //put_user( rxFifoCounter, buffer++ );
  347.     put_user( rx, buffer++ );
  348.  
  349.     length--;
  350.     byte_read++;
  351.     }
  352.  
  353. #if defined(DEBUG_OUTPUT_ENABLED)
  354. if (curBufferLoad>maxBufferLoad)
  355.     {
  356.     maxBufferLoad= curBufferLoad;
  357.     printk ("max buffer load = %d\n", maxBufferLoad);
  358.     }
  359. #endif
  360.  
  361. return byte_read;
  362. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement