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 }; |