打印
[ZLG-MCU]

SPI测试不能进入中断为什么?

[复制链接]
1535|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwsino|  楼主 | 2008-4-30 16:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
spi, ev, dc, TI, se
SPI中断进入不了。不知道是为什么啊
#include "sys/device.h"
#include "stdlib.h"
#include "config.h"
#include "spi.h"
#include "string.h"
#include "stdio.h"
#include "sys/irqreg.h"

extern void SpiInterrupt(void);

NUTDEVICE *curdev;//当前操作的设备指针信息

int SpiArmInput(NUTDEVICE *dev)
{
    IFSTREAM *ifs;
    pSpiDCB   dcb;
    INT8U    devnum;
    INT32U *ret=0;
    INT8U err;
    
    
    devnum = dev->dev_base;
    ifs = dev->dev_icb;
    dcb = dev->dev_dcb;
    
    if(ifs->if_rd_idx == ifs->if_rx_idx)
    {
        if(devnum)
            S1PDR = 0x00;
        else
            S0PDR = 0x00;
            
        do
        {
            ret = (INT32U*)OSMboxPend(dcb->SPIReviceMbox,20,&err);
        }while((ifs->if_rd_idx == ifs->if_rx_idx)||(err == OS_TIMEOUT));
    }
    
    return (int)ret;
}

int SpiArmOutput(NUTDEVICE *dev)
{
    IFSTREAM *ifs = dev->dev_icb;
    
    if(ifs->if_tx_idx == ifs->if_wr_idx)
        return 1;
    
    if(dev->dev_base)
        S1PDR = ifs->if_tx_buf[ifs->if_tx_idx];
    else
        S0PDR = ifs->if_tx_buf[ifs->if_tx_idx];
    ifs->if_tx_idx++;
    
    while(!(S0PSR & 0x80))
        continue;
    
    return 0;
}

void SPI_Exception(void)
{
    INT8U State;
    SpiDCB *dcb;
    IFSTREAM *ifs = curdev->dev_icb;
    dcb = curdev->dev_dcb;
    
    State = S1PSR;
    
    OS_ENTER_CRITICAL();
    if(State&0x80)
    {
        switch(dcb->WorkProcess)
        {
        case IsReading:
            if(ifs->if_rd_idx == ifs->if_rx_idx + 1)
            {
                OSMboxPost(dcb->SPIReviceMbox,(void*)OS_READOVER);
            break;
            }
            
            ifs->if_rx_buf[ifs->if_rx_idx] = S0PDR;
            ifs->if_rx_idx++;
            dcb->rdsize--;
            if(dcb->rdsize == 0)
                OSMboxPost(dcb->SPIReviceMbox,(void*)OS_READOVER);
            else
              if(curdev->dev_base)
                S1PDR = 0x00;//继续产生读取时钟进行数据的读取操作
              else
                  S0PDR = 0x00;
            break;
        case IsWriting:
            if(ifs->if_wr_idx == ifs->if_tx_idx)
            {
                OSMboxPost(dcb->SPIReviceMbox,(void*)OS_SENDOVER);
                break;
            }
            
            if(curdev->dev_base)
            {
                S1PDR = ifs->if_tx_buf[ifs->if_tx_idx];
                ifs->if_tx_idx++;
                break;
            }
            else
            {
                S0PDR = ifs->if_tx_buf[ifs->if_tx_idx];
                ifs->if_tx_idx++;
                break;                
            }
            break;
        }
    }
    
    S0PINT = 0x01;
    VICVectAddr = 0x00000000;
    OS_EXIT_CRITICAL();
}
int SpiFlush(NUTDEVICE *dev)
{
    pSpiDCB dcb = dev->dev_dcb;
    
    dcb->WorkProcess = IsWriting;
    
    (*dcb->Enable)();//使能操作芯片
    if(SpiArmOutput(dev))
    {
        (*dcb->Disable)();//暂停芯片操作
        return -1;    
    }
    printf("595 Write over\n");
    if((int)OSMboxPend(dcb->SPIReviceMbox,OS_TICKS_PER_SEC*2,NULL) == OS_SENDOVER)
    {
        (*dcb->Disable)();//暂停芯片操作
            
        return 0;
    }
    
    (*dcb->Disable)();//暂停芯片操作

    
    return -1;
}
int SPI_Init(NUTDEVICE *dev)
{
    pSpiDCB dcb = dev->dev_dcb;
    
    dcb->WorkProcess = IsIdle;
    
    if(dev->dev_base)
    {
        
    }
    else
    {
        PINSEL0 = (PINSEL0 & 0xFFFFC0FF) | 0x1500;  /* 选择管脚为SPI */
        
    }
    

    
    return 0;
}

int SPI_Close(NUTFILE *fp)
{
    NUTDEVICE *dev = fp->nf_dev;
    pSpiDCB dcb = dev->dev_dcb;

    if(dcb->SPIReviceMbox)
    {
        OSMboxDel(dcb->SPIReviceMbox,OS_DEL_ALWAYS,NULL);
    }
    free(fp);
    
    dcb->Working = IsFree;
    curdev       = 0x0000;
    return 0;
}

NUTFILE* SPI_Open(NUTDEVICE *dev,const char *name,int mode,int acc)
{
    
    NUTFILE *fp = (NUTFILE*)malloc(sizeof(NUTFILE));
    pSpiDCB dcb = dev->dev_dcb;
    INT8U  state;
    
    
    fp->nf_next = 0;
    fp->nf_dev = dev;
    fp->nf_fcb = 0;
    
    curdev     = dev;
           
    while(dcb->Working == IsUsed)
        OSTimeDly(10);
        
    dcb->Working = IsUsed;//打开此设备时将会占用此功能
    if(dcb->SPIReviceMbox == (OS_EVENT*)0)
    {
        dcb->SPIReviceMbox = OSMboxCreate(NULL);
    }
    else
    {
        OSMboxAccept(dcb->SPIReviceMbox);//清除当前消息        
    }
    
    if(dev->dev_base)
    {
         state  = S1PSR;
        if(Fpclk/dcb->baudrate > 8)
         S1PCCR = Fpclk/dcb->baudrate;
        else
         S1PCCR = 8;
         //模式设置操作
         S1PCR  = dcb->WorkMode;
        
    }    
    else
    {
        state  = S0PSR;
        if(Fpclk/dcb->baudrate > 8)
         S0PCCR = Fpclk/dcb->baudrate;
        else
         S0PCCR = 8;
         S0PCR  = dcb->WorkMode;
                 
    }

    VICVectAddr7 =     (unsigned long)SpiInterrupt;
    VICVectCntl7 = 0x20+0x0A;
    VICIntEnable |= (1<<7);
    
//    if(dev->dev_base)
//    {
//        PINSEL1 = (PINSEL1 & 0XFFFFFF03)|0X000000A8;
        NutIrqRegister(SpiInterrupt,dev->dev_irq,11);
//    }
//    else
//    {
//        PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00001500; // /* 选择管脚为SPI*/ 
//        NutIrqRegister(SpiInterrupt,dev->dev_irq,10);
//    }

    return fp;
}

int SPI_Write(NUTFILE *fp,const void *buffer,int size)
{
    NUTDEVICE *dev = fp->nf_dev;
    IFSTREAM *ifs = dev->dev_icb;
    INT8U *pc = (INT8U*)buffer;
    
    if(buffer == 0)
        (*ifs->if_flush)(dev);
    while(size--)
    {    
        if(ifs->if_tx_idx == (ifs->if_wr_idx+1))
        {
            (*ifs->if_flush)(dev);
        }
        else
        {
            ifs->if_tx_buf[ifs->if_wr_idx] = *pc;
            pc++;
            ifs->if_wr_idx++;
        }
    }
    
    return (*ifs->if_flush)(dev);
    
}

int SPI_Read(NUTFILE *fp,void *buffer,int size)
{

    NUTDEVICE *dev = fp->nf_dev;
    IFSTREAM *ifs = dev->dev_icb;
    pSpiDCB dcb = dev->dev_dcb;
    INT8U *Pointer = (INT8U*)buffer;
    INT8U rc = 0;
    
    dcb->rdsize = size;
    dcb->WorkProcess = IsReading;
    
    if(size == 0)
      return -1;
    
    (*ifs->if_input)(dev);
    
    while(size--)
    {
        if((ifs->if_rd_idx == ifs->if_rx_idx)&&rc)
            break;
        *Pointer = ifs->if_rx_buf[ifs->if_rd_idx];
        ifs->if_rd_idx++;
        Pointer++;
        rc++;
    }
    return rc;
}
//获得端口的状态信息
int GetStatus(NUTDEVICE *dev,INT8U *status)
{
    return 0;
}

int SPI_Control(NUTDEVICE *dev,int req,void *conf)
{
//    pSpiDCB dcb = dev->dev_dcb;
    INT32U    *lv  =(INT32U*)conf;
    INT32U  longV= *lv;
//    INT16U  sv   = (INT16U)longV;
    //INT8U   bv   = (INT8U)sv;
    
    switch(req)
    {
    case SPI_SETSPEED:
        if(dev->dev_base)
        {            
            if(Fpclk/longV > 8)
             S1PCCR = Fpclk/longV;
            else
             S1PCCR = 8;
        }    
        else
        {
            if(Fpclk/longV > 8)
             S0PCCR = Fpclk/longV;
            else
             S0PCCR = 8;
             
        }
     break;
     
    }
    
    
    return 0;
}
/*******************************************************************
    由于不同的设备的操作可能会出现不一样的配置要求,故在设计初始化
    时进行分开设计的理念这样可以实现不同的设备间的求同存异的目标
    以下的内容为595专用模块区
 ******************************************************************/

void HC595Enable(void)
{
    PINSEL0 = PINSEL0 & 0XFFFCFFFF;
    IO0DIR  = IO0DIR | (1<<8);
    IO0CLR  |= (1<<8);
}
void HC595Disable(void)
{
    PINSEL0 = PINSEL0 & 0XFFFCFFFF;
    IO0DIR  = IO0DIR | (1<<8);
    IO0SET  |= (1<<8);

}

int HC595_Init(NUTDEVICE *dev)
{
    pSpiDCB dcb = dev->dev_dcb;
    IFSTREAM *ifs = dev->dev_icb;

    if(dev->dev_base)
    {
        PINSEL1 = (PINSEL1 & 0XFFFFFF03)|0X000000A8;
    //    NutIrqRegister(SpiInterrupt,dev->dev_irq,11);
    }
    else
    {
        PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00005500; // /* 选择管脚为SPI*/ 
    //    NutIrqRegister(SpiInterrupt,dev->dev_irq,10);
    }
            
   if(dcb)
    memset(dcb,0,sizeof(SpiDCB));
   if(ifs)
    memset(ifs,0,sizeof(IFSTREAM)); 
    
    
    dcb->WorkMode = (1<<MSTR)|(1<<CPHA)|(1<<SPIE);      
    dcb->WorkProcess = IsIdle;
    dcb->baudrate    = 400000;
    dcb->Enable      = HC595Enable;
    dcb->Disable     = HC595Disable;
    
    ifs->if_rx_idx = 0;
    ifs->if_tx_idx = 0;
    ifs->if_wr_idx = 0;
    ifs->if_rd_idx = 0;
    ifs->if_input  = SpiArmInput;
    ifs->if_output = SpiArmOutput;
    ifs->if_flush  = SpiFlush;
    printf("595Initilation\n");
    
    return 0;    
}
SpiDCB dcb595;
IFSTREAM ifs595;

NUTDEVICE dev595=
{
    0,
    {'l','s','5','9','5',0,0,0,0},
    IFTYP_CHAR,
    0,
    OS_SPI0_PRIO,
    &ifs595,
    &dcb595,
    HC595_Init,
    SPI_Control,
    SPI_Read,
    SPI_Write,
    SPI_Open,
    SPI_Close,
    NULL    
};

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

73

帖子

1

粉丝