我把代码贴出来 还请专家帮忙看看如何修改
现在主要的问题就是刚配置完中断 中断处理函数就会被执行 根本等不到数据到来 而且会影响到其他任务无法继续执行 即使在中断处理函数里把中断关闭并清中断
// ST serial flash commands
#define ST_WREN 0x06 // write enable
#define ST_WRDI 0x04 // write disable
#define ST_RDSR 0x05 // read status register
#define ST_WRSR 0x01 // write status register
#define ST_READ 0x03 // read data bytes
#define ST_FAST_READ 0x0B // read data bytes at higher speed
#define ST_PP 0x02 // page program
#define ST_SE 0xD8 // sector erase
#define ST_BE 0xC7 // bulk erase
#define ST_RES 0xAB // release from deep power-down and read electronic signature
#define ST_RMD 0x90 // read manufaction and device code
// status flags
#define ST_WIP 0x01 // write in progress
#define TIMOD_RX 0x00
#define TIMOD_TX 0x01
#define TIMOD_DMA_RX 0x02
#define TIMOD_DMA_TX 0x03
#define SELECT() *pFIO_FLAG_C = SF_CS
#define DESELECT() *pFIO_FLAG_S = SF_CS
INT32u giSfPage;
INT16u giSfCtr;
INT32u giSfSpiBaud;
#define SPI_DMA_INT_MODE 0
#define SPI_DMA_QUERY_MODE 1
#define DMA5_READ 0
#define DMA5_WRITE 1
OS_EVENT *OSStRxSignal;
OS_EVENT *OSStTxSignal;
int RUNNING;
#if SPI_DMA_INT_MODE
INT8U StRxPostSignal (void)
{
INT8U err;
err = OSSemPost(OSStRxSignal);
return (err);
}
INT8U StRxCreateSignal (void)
{
INT8U err;
OSStRxSignal = OSSemCreate(0);
#if OS_EVENT_NAME_SIZE > 10
OSEventNameSet(OSStRxSignal, (INT8U *)"OS-STRX", &err);
#endif
return (err);
}
INT8U StRxPendSignal (void)
{
INT8U err;
OSSemPend(OSStRxSignal, 0, &err);
return (err);
}
INT8U StTxPostSignal (void)
{
INT8U err;
err = OSSemPost(OSStTxSignal);
return (err);
}
INT8U StTxCreateSignal (void)
{
INT8U err;
OSStTxSignal = OSSemCreate(0);
#if OS_EVENT_NAME_SIZE > 10
OSEventNameSet(OSStTxSignal, (INT8U *)"OS-STTX", &err);
#endif
return (err);
}
INT8U StTxPendSignal (void)
{
INT8U err;
OSSemPend(OSStTxSignal, 0, &err);
return (err);
}
void SPI_DMA5_ISR(void)
{
printf("\nSPI_DMA5_ISR HAPPEN RUNNING = %d\n",RUNNING);
*pSPI_CTL &= ~SPE;
*pDMA5_CONFIG = 0;
if(RUNNING == DMA5_READ)
{
StRxPostSignal();
}
else if(RUNNING == DMA5_WRITE)
{
StTxPostSignal();
}
}
void Init_SPI_Interrupts(void)
{
StRxCreateSignal();
*pSIC_IAR0 = *pSIC_IAR0 & 0xffffffff | 0x00000000;
*pSIC_IAR1 = *pSIC_IAR1 & 0xff0fffff | 0x00300000;
*pSIC_IAR2 = *pSIC_IAR2 & 0xffffffff | 0x00000000;
OS_CPU_RegisterHandler(IVG10, SPI_DMA5_ISR, NOT_NESTED);
//*pDMA5_CONFIG &= ~DI_EN;
*pSIC_IMASK |=0x00002000;
}
#endif
// This function will check what the system clock is based
// on the _MSEL, _DF, and _SSEL values in the PLL_CTL and PLL_DIV registers.
INT32u GetSCLK(void)
{
INT16u tempPLLCTL,tempPLLDIV;
INT16u _MSEL,_SSEL,_DF,_VCO,_SCLK;
INT16u clkin = CLKIN;
tempPLLCTL = *pPLL_CTL;
tempPLLDIV = *pPLL_DIV;
//get _MSEL, _SSEL, _DF
_MSEL = ((tempPLLCTL & 0x7E00) >> 9);
_SSEL = tempPLLDIV & 0x000f;
_DF = tempPLLCTL & 0x0001;
if(_DF == 1) clkin = clkin/2;
_VCO = _MSEL * clkin;
_SCLK = _VCO/_SSEL;
return _SCLK * 1000000;
}
void SfInit(void)
{
INT32u _SCLK = GetSCLK();
// calculate divisor constant
giSfSpiBaud = (_SCLK / 2 / SF_MAX_CLOCK) + 1; // max. 20 MHz
///********************************************************************************
*pFIO_DIR = *pFIO_DIR & 0xFFFB | 0x0004; // set output direction for PF2 SPI select lines
*pFIO_INEN = *pFIO_INEN & 0xFFFB | 0x0000; // ensable input buffers for PF2 GPIO lines
*pFIO_FLAG_D = *pFIO_FLAG_D &0xFFFB | 0x0004; // set PF2 output bits to '1' (deselect SPI)
//*********************************************************************************/
*pSPI_FLG = *pSPI_FLG & 0xFBFB | 0x0400;
}
void _SfOpen(void)
{
*pSPI_BAUD = giSfSpiBaud;
// configure spi port:
// transfer on write, 8-bit data, MSB first,
// master, CPOL = CPHA = 1 (mode 3)
*pSPI_CTL = TIMOD_TX | MSTR | CPOL | CPHA | SPE;
}
void _SfClose(void)
{
DESELECT();
// disable SPI
*pSPI_CTL = 0;
}
BYTEu _SpiSendRcv(BYTEu data)
{
// while ((*pSPI_STAT & TXS)); // wait for transfer buffer empty
*pSPI_TDBR = data; // send data
while ((*pSPI_STAT & TXS)); // wait for transfer buffer empty
while (!(*pSPI_STAT & RXS)); // wait for receive buffer full
// while ((*pSPI_STAT & SPIF) == 0); // wait for transfer complete
return *pSPI_RDBR; // get input
}
// wait while write in progress
void _SfWaitWhileWIP(void)
{
SELECT();
_SpiSendRcv(ST_RDSR);
while (_SpiSendRcv(0) & ST_WIP);
DESELECT();
}
void _SfSendCmd(BYTEu cmd)
{
// _SfWaitWhileWIP();
SELECT();
_SpiSendRcv(cmd);
DESELECT();
}
void _SfSendCmdAddr(BYTEu cmd, INT32u addr)
{
// _SfWaitWhileWIP();
SELECT();
_SpiSendRcv(cmd);
_SpiSendRcv((addr >> 16) & 0xff);
_SpiSendRcv((addr >> 8) & 0xff);
_SpiSendRcv((addr ) & 0xff);
}
void SfBWriteStart(INT32u addr)
{
_SfOpen();
_SfSendCmd(ST_WREN);
_SfSendCmdAddr(ST_PP, addr);
giSfPage = addr & ~(SF_PAGESIZE - 1);
giSfCtr = SF_PAGESIZE - (addr & (SF_PAGESIZE - 1)); // remaining bytes to the page boundary
}
void SfBWriteEnd(void)
{
DESELECT();
_SfWaitWhileWIP();
_SfClose();
}
void SfBWrite(BYTEu data)
{
if (giSfCtr IS 0) { // reached page boundary: start internal write cycle
DESELECT(); // release chip select to initiate write cycle
giSfCtr = SF_PAGESIZE - 1; // we will send one byte in this cycle already, so start from PAGESIZE - 1!
giSfPage += SF_PAGESIZE;
_SfWaitWhileWIP();
_SfSendCmd(ST_WREN);
_SfSendCmdAddr(ST_PP, giSfPage); // start new block
} else {
giSfCtr--;
}
_SpiSendRcv(data);
}
// high level communication
void SfWrite(INT32u addr, BYTEu data)
{
_SfOpen();
_SfSendCmdAddr(ST_PP, addr);
_SpiSendRcv(data);
_SfClose();
}
BYTEu SfRead(INT32u addr)
{
BYTEu data;
_SfOpen();
_SfSendCmdAddr(ST_READ, addr);
data = _SpiSendRcv(0);
_SfClose();
return data;
}
void SfBReadStart(INT32u addr)
{
_SfOpen();
_SfSendCmdAddr(ST_READ, addr);
}
BYTEu SfBRead(void)
{
return _SpiSendRcv(0);
}
void SfBReadEnd(void)
{
_SfClose();
}
void SfEraseSector(INT32u addr)
{
_SfOpen();
_SfSendCmd(ST_WREN);
_SfSendCmdAddr(ST_SE, addr); // sector erase
DESELECT();
_SfWaitWhileWIP();
_SfClose();
}
void SfErase(void)
{
_SfOpen();
_SfSendCmd(ST_WREN);
_SfSendCmd(ST_BE); // bulk erase
_SfWaitWhileWIP();
_SfClose();
}
BYTEu SfGetSignature(void)
{
BYTEu sig;
_SfOpen();
_SfSendCmdAddr(ST_RES, 0);
_SpiSendRcv(0); // send dummy byte to clock in signature
sig = *pSPI_RDBR;
_SfClose();
return sig;
}
INT16u SfGetManufactionAndDeviceCode(void)
{
INT16u md =0;
_SfOpen();
_SfSendCmdAddr(ST_RMD, 0);
_SpiSendRcv(0); // send dummy byte to clock in signature and give up the first 0x00
//测试结果与文档结果相反,文档中MD在前,DD在后
md =_SpiSendRcv(0);
md |=(_SpiSendRcv(0)<<8)&0xFF00;
_SfClose();
return md;
}
void SfMemWrite(INT32u addr, INT32u count, BYTEu *buf)
{
INT32u ctr = SF_PAGESIZE - (addr & (SF_PAGESIZE - 1)); // remaining bytes to the page boundary
// map DMA5 to SPI
*pDMA5_PERIPHERAL_MAP = 0x5000;
RUNNING = DMA5_WRITE;
while (count) {
_SfOpen();
_SfSendCmd(ST_WREN);
_SfSendCmdAddr(ST_PP, addr);
// reconfigure spi port for DMA transfer:
// DMA transmit, 8-bit data, MSB first, master, CPOL = CPHA = 1 (mode 3)
*pSPI_CTL = TIMOD_DMA_TX | MSTR | CPOL | CPHA;
// Configure DMA5
// 8-bit memory read
*pDMA5_CONFIG = WDSIZE_8;
// Start address of data buffer
*pDMA5_START_ADDR = buf;
// DMA inner loop count
*pDMA5_X_COUNT = ctr;
// Inner loop address increment
*pDMA5_X_MODIFY = 1;
// enable DMA
*pDMA5_CONFIG = (*pDMA5_CONFIG | DMAEN | DI_EN); // interrupt at the end of DMA
//*pDMA5_CONFIG = (*pDMA5_CONFIG | DMAEN); // poll end of DMA
// enable spi
SELECT();
*pSPI_CTL = (*pSPI_CTL | SPE);
StTxPendSignal();
// wait until dma transfers for spi are finished
while ((*pSPI_STAT BITAND TXS) IS 0); // wait for data buffer full
do {
while (*pSPI_STAT BITAND TXS); // wait for data buffer empty
} while (*pSPI_STAT BITAND TXS); // finished if still empty
while ((*pSPI_STAT BITAND SPIF) IS 0); // wait for transfer complete
// disable DMA
*pDMA5_CONFIG = 0;
_SfClose(); // initiate write cycle
_SfOpen();
_SfWaitWhileWIP(); // wait while write in progress
_SfClose();
count -= ctr;
addr += ctr;
buf += ctr;
ctr = (count < SF_PAGESIZE) ? count : SF_PAGESIZE;
}
}
void SfMemRead(INT32u addr, INT32u count, BYTEu *buf)
{
printf(("\n SfMemRead HAPPEN!!!\n"));
RUNNING = DMA5_READ;
// map DMA5 to SPI
*pDMA5_PERIPHERAL_MAP = 0x5000;
_SfOpen();
_SfSendCmdAddr(ST_READ, addr);
// reconfigure spi port for DMA transfer:
// DMA receive, 8-bit data, MSB first, master, CPOL = CPHA = 1 (mode 3), send zero
*pSPI_CTL = TIMOD_DMA_RX | MSTR | CPOL | CPHA | SZ;
// Configure DMA5
// 8-bit memory write
*pDMA5_CONFIG = WDSIZE_8 | WNR;
// Start address of data buffer
*pDMA5_START_ADDR = buf;
// DMA inner loop count
*pDMA5_X_COUNT = count;
// Inner loop address increment
*pDMA5_X_MODIFY = 1;
// enable DMA
*pDMA5_CONFIG = (*pDMA5_CONFIG | DMAEN | DI_EN); // interrupt at the end of DMA
//*pDMA5_CONFIG = (*pDMA5_CONFIG | DMAEN); // poll end of DMA
// enable spi
SELECT();
*pSPI_CTL = (*pSPI_CTL | SPE);
StRxPendSignal();
// wait until dma transfers from spi are finished
while (*pDMA5_IRQ_STATUS BITAND DMA_RUN); // wait for DMA done
// disable DMA
*pDMA5_CONFIG = 0;
_SfClose();
}