I set Slave mode in 56F8037, set receive FIFO 2words, transmite FIFO 2words。
DSP work into it's Interrupt Service Routine(void SS1_InterruptRx(void)) all the time.
Why? Is there any bug in FIFO control on 56F8037? or my code problem?
I modify source from code generated by PE. Code as below:
void SS1_Init(void)
{
/* QSPI0_SCTRL: SPR2=0,SPR1=0,SPR0=0,DSO=0,ERRIE=0,MODFEN=0,SPRIE=0,SPMSTR=0,CPOL=1,CPHA=1,SPE=0,SPTIE=0,SPRF=0,OVRF=0,MODF=1,SPTE=0 */
setReg(QSPI0_SCTRL,0xC2); /* Set control register */
/* QSPI0_DSCTRL: WOM=0,??=0,??=0,BD2X=0,SS_IN=0,SS_DATA=0,SS_ODM=0,SS_AUTO=0,SS_DDR=0,SS_STRB=0,SS_OVER=0,??=0,DS3=1,DS2=1,DS1=1,DS0=1 */
setReg(QSPI0_DSCTRL,0x0F); /* Set data size and control register */
/* ??=0, TRWM1=1, TRWM0=0, ??=0, RFWM1=0, RFWM0=1, ??=0, FIFO_ENA=1 */
setReg(QSPI0_FIFO,0x45); /* Set FIFO register. ljr.add 2009.3.10 */
SerFlag = 0; /* Reset all flags */
ErrFlag = 0; /* Reset all flags in mirror */
SS1_EnEvent = FALSE; /* Disable events */
EnUser = FALSE; /* Disable device */
SS1_InpLen = 0; /* No char in the receive buffer */
InpPtrW = InpPtrR = InpBuffer; /* Set pointer on the first item in the receive buffer */
SS1_OutLen = 0; /* No char in the transmit buffer */
OutPtrW = OutPtrR = OutBuffer; /* Set pointer on the first item in the transmit buffer */
HWEnDi(); /* Enable/disable device according to the status flags */
setReg(QSPI0_DXMIT,0xFF);
}
Interrupt service routine code:
dword dwDataWT[128]={0};
dword dwDataRD[128]={0};
#pragma interrupt alignsp saveall
void SS1_InterruptRx(void)
{
register word Data1; /* Temporary variable for data */
register word Data2; /* Temporary variable for data */
LED3_On();
getReg(QSPI0_SCTRL);
if (getRegBit(QSPI0_SCTRL,OVRF)) /* Occured any overflow condition between QSPI0_SCTRL and QSPI0_DRCV reading? */
{
LED1_On();
getReg(QSPI0_DRCV); /* Clear the overflow flag */
}
if (getRegBit(QSPI0_SCTRL,MODF))
{
LED1_On();
setRegBit(QSPI0_SCTRL,MODF);
}
if (getRegBit(QSPI0_SCTRL, SPTE))
{
LED2_On();
}
if (getRegBit(QSPI0_SCTRL,SPRF))
{
LED1_On();
Data1 = getReg(QSPI0_DRCV); /* Read data from receiver */
Data2 = getReg(QSPI0_DRCV); /* Read data from receiver */
if (Data1&0x8000)//ARM要读DSP的数据
{
Data2 = (Data1>>8)&0x007F;
setReg(QSPI0_DXMIT, (word)(dwDataRD[Data2]>>16));
setReg(QSPI0_DXMIT, (word)dwDataRD[Data2]);
}
else //ARM写数据给DSP
{
dwDataWT[Data1>>8] = (dword)Data1<<16+(dword)Data2;
setReg(QSPI0_DXMIT,0xFFFF);
setReg(QSPI0_DXMIT,0xFFFF);
}
}
LED3_Off();
LED2_Off();
LED1_Off();
}
after i set interrupt priority to medium priority, and rewrite ISR, it ok now.
but i don't know the reason yet.
dword dwDataWT[128]={0};
dword dwDataRD[128]={0};
#pragma interrupt alignsp saveall
void SS1_InterruptRx(void)
{
register word Data1; /* Temporary variable for data */
register word Data2; /* Temporary variable for data */
register word index;
LED3_On();
getReg(QSPI0_SCTRL); /* Dummy read the device error register */
Data1 = getReg(QSPI0_DRCV); /* Dummy read data from receiver */
Data2 = getReg(QSPI0_DRCV); /* Dummy read data from receiver */
if (getRegBit(QSPI0_SCTRL,OVRF)) { /* Occured any overflow condition between QSPI0_SCTRL and QSPI0_DRCV reading? */
getReg(QSPI0_DRCV); /* Clear the overflow flag */
}
index = (Data1>>8)&0x007F;
if (Data1&0x8000)//ARM要读DSP的数据
{
setReg(QSPI0_DXMIT, (word)(dwDataRD[index]>>16));
setReg(QSPI0_DXMIT, (word)dwDataRD[index]);
}
else //ARM写数据给DSP
{
dwDataWT[index] = Data1;
dwDataWT[index]<<=16;
dwDataWT[index]+= Data2;
setReg(QSPI0_DXMIT,0xFFFF);
setReg(QSPI0_DXMIT,0xFFFF);
}
LED3_Off();
}
void SS1_Init(void)
{
/* QSPI0_SCTRL: SPR2=0,SPR1=0,SPR0=0,DSO=0,ERRIE=0,MODFEN=0,SPRIE=0,SPMSTR=0,CPOL=1,CPHA=1,SPE=0,SPTIE=0,SPRF=0,OVRF=0,MODF=1,SPTE=0 */
setReg(QSPI0_SCTRL,0xC2); /* Set control register */
/* QSPI0_DSCTRL: WOM=0,??=0,??=0,BD2X=0,SS_IN=0,SS_DATA=0,SS_ODM=0,SS_AUTO=0,SS_DDR=0,SS_STRB=0,SS_OVER=0,??=0,DS3=1,DS2=1,DS1=1,DS0=1 */
setReg(QSPI0_DSCTRL,0x0F); /* Set data size and control register */
setReg(QSPI0_FIFO,0x45); /* Set FIFO register. ljr.add 2009.3.10 */
setRegBit(QSPI0_SCTRL,SPE); /* Enable device */
setReg(QSPI0_DXMIT,SS1_EOF); /* Store the empty char to the transmit register */
setRegBits(QSPI0_SCTRL,(QSPI0_SCTRL_ERRIE_MASK|QSPI0_SCTRL_SPRIE_MASK)); /* Enable receive and error interrupts */
/* ??=0, TRWM1=1, TRWM0=0, ??=0, RFWM1=0, RFWM0=1, ??=0, FIFO_ENA=1 */
}
I check LED1/LED2/LED3 status with scope, find DSP work in Interrupt Service Routine, with LED3 always toggle it's status. LED2 and LED1 correct. But I don't know what is the interrupt source.
who can give me a hand, thanks all.