⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi.c

📁 fft 2410 linux 部分驱动 报扩 ad da 数码管 led
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                                  西安傅立叶电子有限公司
**                                     研    发    部
**                              http://www.FFTChina.com
**-----------------------------------------文件信息-----------------------------------------------------
**文   件   名: cantest.c
**创   建   人: 
**最后修改日期: 2005年6月30日
**描        述: CAN模块测试驱动程序(查询模式)
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include  <linux/capability.h>
#include  <linux/smp_lock.h>
#include  <linux/module.h>
#include <linux/spinlock.h>
#include <linux/poll.h>

#include  <asm/hardware.h>
#include  <asm/io.h>
#include  <linux/irq.h>
#include  <linux/devfs_fs_kernel.h>
#include  <linux/init.h>
#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
#include  "linux/smp_lock.h"
#endif

#define BIT_DMA1       (0x1<<18)

#define  FFTspi_MAJOR  18
#define ClearPending(bit) {SRCPND = bit;INTPND = bit;INTPND;}   
                
char   kernel_version[]=UTS_RELEASE;
devfs_handle_t  dev_handle3; 

volatile int tx_dma1Done,rx_dma1Done;
int SpiMode = 1;
unsigned char SPI_BUFFER[128]; 
#define DEBUG

void SPI_Port_Init(int MASorSLV,unsigned long arg)
{
    GPEUP&=~(0x3800);              //config clk pull up
    GPEUP|=0x2000;                 //spiclk  
    GPECON=((GPECON&0xf03fffff)|0xa800000);//config spi pin func
    GPGUP|=0x4;                   // nSS0 config pull up
    if(MASorSLV==1)
    {
        GPGCON=((GPGCON&0xffffffcf)|0x10); // Master(GPIO_Output)
        GPGDAT|=0x4; // Activate nSS 
    }
    else
    	GPGCON=((GPGCON&0xffffffcf)|0x30); // Slave(nSS)
    //Step1. SPI init
    SPPRE0=arg;	                           //50/2(arg+1);
    //if PCLK=50Mhz,SPICLK=25Mhz  //2 divide
 }
/*******************************************************
**  函数原形:irq_handler(int irq, void *dev_id, struct pt_regs *regs)
**	 参数:   irq        : 中断号
**	          dev_id     : 申请时告诉系统的设备标识
**	          regs       : 中断发生时的寄存器内容
**  函数说明:中断服务程序
*******************************************************/
void  Dma1Tx_Int(int irq, void *dev_id, struct pt_regs *regs)
{
  #ifdef DEBUG  
    printk("ok int\n");
  #endif
    tx_dma1Done=1;
    rx_dma1Done=1;
    INTMSK|=BIT_DMA1;
    ClearPending(BIT_DMA1);
}
/*******************************************************
*函数原形:read_fftspi(struct file *file, char *buf, size_t count,loff_t *f_pos)
*参数:        buf  : 传入该函数的数据缓冲区指针
*	           count:CAN的通道号
*返回值 : 0
*函数说明:读出接收到的CAN数据
*******************************************************/

static int  read_fftspi(struct file *file, char *buffer, size_t count,loff_t *f_pos)
{	
	int flags,i;
    unsigned char *dmabuf;
    unsigned int dmasize = count;
    unsigned int dmaphys = 0;
    unsigned char *rx_ptr;
    do {
		dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,dmasize, &dmaphys);
		if (!dmabuf) 
			printk("erro dmabuf\n");
	  } while (!dmabuf && dmasize);
    rx_dma1Done=0;
    local_irq_save(flags);
    INTMSK=INTMSK&(~(BIT_DMA1));    //forbid
    SPCON0=(2<<5)|(SpiMode<<4)|(SpiMode<<3)|(1<<2)|(0<<1)|(1<<0);//DMA1,en-SCK,master,low,A,TAGD    
    if(SpiMode)GPGDAT&=0xfffffffb;
    SPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    //Step2. DMA1 init 
    DISRC1=(unsigned)0x59000014;//Address of SPRDAT Register
    DISRCC1=(1<<1)|(1);		//APB(SPI), fix
    DIDST1=DMA_BASE_ADDR(dmaphys);	//Address of Memory
    DIDSTC1=(0<<1)|(0);		//AHB(Memory), inc
    DCON1=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(3<<24)|(1<<23)|(1<<22)|(0<<20)|(dmasize);
    //handshake, sync PCLK, TC int, single tx, single service, SPI, H/W request, 
    //off-reload, byte, 128Bytes
    DMTRIG1=(0<<2)|(1<<1)|(0);    //run, DMA1 channel on, no-sw trigger 
    local_irq_restore(flags);
    while(rx_dma1Done==0);
    while(!(SPSTA0&0x1));           //Check Rx ready stat
    rx_ptr = dmabuf ;//¿ʒՉ눫һ¿ꀕµٖ·
    *(rx_ptr + dmasize)=SPRDAT0;
#ifdef DEBUG    
    for(i=1; i <=dmasize; i++)
	{
 		printk("get dat is %c\n",*(rx_ptr+i));
    }
#endif
    copy_to_user(buffer,dmabuf+1,count);
    if(SpiMode)GPGDAT|=0x4;         // Deactivate nSS 
    consistent_free(dmabuf,dmasize,dmaphys);
    return 0;
	
   
}

/*******************************************************
*函数原形:write_fftspi(struct file *file,const char *buf,size_t count,loff_t *f_pos)
*参数:    buf  : 传入该函数的数据缓冲区指针
*	       count:CAN的通道号
*返回值 : 0 说明成功写入
*函数说明:向CAN总线发送数据
*******************************************************/

static int  write_fftspi(struct file *file,const char *buf,size_t count,loff_t *f_pos)
{    
	int i,flags;
    unsigned char *dmabuf;
    int dmasize = count;
    int dmaphys = 0;
    unsigned char *tx_ptr;
    do {
		dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,dmasize, &dmaphys);
		if (!dmabuf) 
			printk("erro dmabuf\n");
	} while (!dmabuf && dmasize);
    copy_from_user(dmabuf, buf,dmasize);
    tx_ptr = dmabuf ;//
  #ifdef DEBUG
    for(i=0; i < dmasize; i++)
	{
		printk("send dat is %c\n",*(tx_ptr+i));
    }
  #endif
    tx_dma1Done=0;
    local_irq_save(flags);
    INTMSK=INTMSK&(~(BIT_DMA1));    //forbid
    SPCON0=(2<<5)|(SpiMode<<4)|(SpiMode<<3)|(1<<2)|(0<<1)|(0<<0);//DMA1,en-SCK,master,low,B,normal    
    SPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    DISRC1=DMA_BASE_ADDR(dmaphys);	//Address of Memory
    DISRCC1=(0<<1)|(0);		        //AHB(Memory), inc
    DIDST1=(unsigned)0x59000010;    //Address of SPTDAT Register
    DIDSTC1=(1<<1)|(1);		        //APB(SPI), fix
    DCON1=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(3<<24)|(1<<23)|(1<<22)|(0<<20)|(dmasize); //handshake, sync PCLK, TC int, single tx, single service, SPI, H/W request,off-reload, byte, 128Bytes
    if(SpiMode) GPGDAT&=0xfffffffb; // Activate nSS nSS active
    DMTRIG1=(0<<2)|(1<<1)|(0);      //run, DMA1 channel on, no-sw trigger 
    local_irq_restore(flags);
    while(tx_dma1Done==0);
    while(!(SPSTA0&0x1));
    consistent_free(dmabuf,dmasize,dmaphys);
#ifdef DEBUGSR    
    while(!(SPSTA0&0x1));           //Check Rx ready stat
    {
       i = SPRDAT0;
       printk("get dat is %c\n",i);
    }
#endif
    if(SpiMode)GPGDAT|=0x4;         // Deactivate nSS 
    return 0;
	
}
/*******************************************************
*函数原形:open_fftspi(struct inode *inode,struct file *file)
*参数:               
*返回值 : 
*函数说明:
*******************************************************/
static int open_fftspi(struct inode *inode,struct file *file)
{   
    MOD_INC_USE_COUNT;
    return 0;
}
/*******************************************************
*函数原形:open_fftspi(struct inode *inode,struct file *file)
*参数:               
*返回值 : 
*函数说明:
*******************************************************/
static int release_fftspi(struct inode *inode,struct file *file)
{
    MOD_DEC_USE_COUNT;
    return 0;
}
/***************************************************************************************************
** function descrp:
** arg:     cmd:    0: slave mode 1: master mode
            arg:    Baud rate = 50M / 2 / (arg + 1)
** detail:     
**************************************************************************************************/
static int ioctl_fftspi(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
   int flags;
   local_irq_save(flags);
   SpiMode = cmd;
   SPI_Port_Init(cmd,arg);
   local_irq_restore(flags);
   return 0;
}
/*******************************************************
*函数原形:open_fftspi(struct inode *inode,struct file *file)
*参数:               
*返回值 : 
*函数说明:
*******************************************************/

static unsigned int s3c2410_kbd_poll(struct file *filp, struct poll_table_struct *wait)
{
 
  return 0;
}
/***************************************
** 函数指针结构: file_operations
** 说明        :
***************************************/
struct file_operations fftspi_fops={

  	read :      read_fftspi,
    write:      write_fftspi,
	ioctl:	    ioctl_fftspi,
	open :	    open_fftspi,
    release:    release_fftspi,
    poll :      s3c2410_kbd_poll,  
};
/******************************************************
**  初始化模块:在加载模块时候调用
**  函数原形  : init_module(void)
**  说    明  :不用修改
******************************************************/
 static int __init  fftspi0_init_module(void)
{
   int result;
   dev_handle3 = devfs_register( NULL, "fftspi", DEVFS_FL_DEFAULT, FFTspi_MAJOR, 0, S_IFCHR, &fftspi_fops, NULL);
   result = request_irq(IRQ_DMA1,Dma1Tx_Int,SA_INTERRUPT,"fftspidma",NULL);
   if (result < 0) 
   { 
		printk(KERN_INFO "test: can't install interrupt\n"); 
	
   }
   printk("congraulation,fftspi are successful registed\n");
   return 0;
}
/*******************************************************
**  函数原形 : cleanup_module(void)
**  说明     : 在卸载模块时调用
******************************************************/
static void __exit fftclrspi0_module(void)
{
   SPCON0=(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//poll,dis-SCK,master,low,B,normal
   devfs_unregister (dev_handle3);
   free_irq(IRQ_DMA1, NULL);
   printk("exit fftspi\n");

}
MODULE_LICENSE("GPL");

module_init(fftspi0_init_module);
module_exit(fftclrspi0_module);



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -