Post Go back to editing

SC587 communicates with SPI flash via DMA

Category: Software
Product Number: ADSP-SC587
Software Version: sc587

Hi

    I encountered the following problem when communicating with MXIC SPI flash using sc587 SPI2+DMA

    When using the 0x90 command to obtain the manufacturer and device ID of spi flash, setting the ReceiverBytes in ADI-SPI-TRANCEIVER to 2 does not receive a normal reply. When set to 8, multiple replies are received. May I ask what is the reason for the problem?

    The code and results are as follows


/* number of tests performed */
#define TEST_NUM 2u
/* maximum prologue buffer size */
#define PROLOGUESIZE 4u
/* maximum receive buffer size */
#define RXBUFFERSIZE 32u

static uint8_t SpuMemory[ADI_SPU_MEMORY_SIZE];
uint8_t ProBuffer1[PROLOGUESIZE] = {0x90u, 0x00u, 0x00u, 0x01u};
uint8_t RxBuffer1[RXBUFFERSIZE] = {0x00u, 0x00u, 0x00u};
/* JEDEC ID prologue command [1 byte], 0x9F */
uint8_t ProBuffer2[PROLOGUESIZE] = {0x9Fu, 0x00u, 0x00u, 0x00u};
uint8_t RxBuffer2[RXBUFFERSIZE] = {0x00u, 0x00u, 0x00u};
/* transceiver configurations */
/* Manufacturer ID transceiver, 4 byte prologue followed by 2 byte rx buffer, expected readback result [0xEF, 0x15] */
ADI_SPI_TRANSCEIVER Xcv0 = {&ProBuffer1[0], 4u, NULL, 0u, &RxBuffer1[0], 8u};
/* JEDEC ID transceiver, 1 byte prologue followed by 3 bytes rx buffer, expected readback result [0xEF, 0x40, 0x16] */
ADI_SPI_TRANSCEIVER Xcv1 = {&ProBuffer2[0], 1u, NULL, 0u, &RxBuffer2[0], 3u};
static ADI_SPI_HANDLE phSPI;


void SPI_Callback(void *pCBParam, uint32_t nEvent, void *pArg)
{
switch(nEvent)
{
case (uint32_t)ADI_SPI_TRANSCEIVER_PROCESSED:
/* set test end callback flag when last transceiver in test array is processed */
if((ADI_SPI_TRANSCEIVER *)pArg == TransceiverTests[TEST_NUM-1])
{
CallbackTestEndFlag = true;
}
/* set callback flag */
CallbackFlag = true;
break;
default:
break;
}
}

/* callback mode with interrupts spi flash readback test */
uint32_t CallbackTest(ADI_SPI_TRANSCEIVER *pTestArray[], uint32_t NumTests)
{
uint32_t TestIndex;
uint32_t i;
uint32_t Result = 0u;

/* reset callback flags */
CallbackFlag = false;
CallbackTestEndFlag = false;

if (Result == 0u)
{
/* enable callbacks */
Result = (uint32_t)adi_spi_RegisterCallback(hSpi, SPI_Callback, NULL);
}

/* submit the test transceivers */
for(TestIndex=0u; TestIndex <NumTests; TestIndex++)
{
if(Result == 0u)
{
/* non-blocking mode submission */
Result = (uint32_t)adi_spi_SubmitBuffer(hSpi, pTestArray[TestIndex]);
}
if(Result != 0u)
{
/* set flag as if test has completed */
CallbackTestEndFlag = true;
}
/* wait here until callback detects a transceiver processed */
while(CallbackFlag != true)
{
/* MISRA compliance */
Result = 0u;
}
/* reset flag */
CallbackFlag = false;

if(Result !=0u)
{
break;
}
}
/* wait for callback function to detect last buffer processed */
while(CallbackTestEndFlag != true)
{
/* MISRA compliance */
Result = 0u;
}
return Result;
}

bool RunSPI(ADI_SPI_HANDLE phSPI)
{

uint32_t Result = 0u;

if (Result == 0u)
{
/* interrupt mode, i.e no dma */
Result = (uint32_t)adi_spi_EnableDmaMode(phSPI, true);
}
if (Result == 0u)
{
/* device in master of the SPI interface */
Result = (uint32_t)adi_spi_SetMaster(phSPI, true);
}
if (Result == 0u)
{
/* SPI slave select in controlled by software not hardware */
Result = (uint32_t)adi_spi_SetHwSlaveSelect(phSPI, false);
}
/* default transceiver mode to read/write */
if (adi_spi_SetTransceiverMode(phSPI, ADI_SPI_TXRX_MODE));
if (Result == 0u)
{
/* send zeros if tx SPI underflows*/
Result = (uint32_t)adi_spi_SetTransmitUnderflow(phSPI, true);
}
if (Result == 0u)
{
/* data transitions on falling edge of clock */
Result = (uint32_t)adi_spi_SetClockPhase(phSPI, false);
}
if (Result == 0u)
{
/* SPI clock is SCLK divided by 1000 + 1 */
Result = (uint32_t)adi_spi_SetClock(phSPI, 3);
}
if (Result == 0u)
{
/* SPI slave select is on SPI slave select 1 pin */
Result = (uint32_t)adi_spi_SetSlaveSelect(phSPI, ADI_SPI_SSEL_ENABLE1);
}
if (Result == 0u)
{
/* SPI data transfers are 8 bit */
Result = (uint32_t)adi_spi_SetWordSize(phSPI, ADI_SPI_TRANSFER_8BIT);
}

if (adi_spi_SetTxWatermark(hSpi,
ADI_SPI_WATERMARK_50,
ADI_SPI_WATERMARK_DISABLE,
ADI_SPI_WATERMARK_DISABLE)) ;

/* generate rx data interrupt when watermark level breaches 50% level */
/* DMA watermark levels are disabled because SPI is in interrupt mode */
if (adi_spi_SetRxWatermark(hSpi,
ADI_SPI_WATERMARK_50,
ADI_SPI_WATERMARK_DISABLE,
ADI_SPI_WATERMARK_DISABLE)) ;

Result = CallbackTest(&TransceiverTests[0], TEST_NUM);


return Result;

}


int main(void)
{
bool bError = PASSED;

/* open SPI */
if (adi_spi_Open(SPI_FLASH_DEVICE_NUM, SpiMemory, (uint32_t)ADI_SPI_DMA_MEMORY_SIZE, &hSpi))
{
bError = FAILED;
}

if (!bError)
{
if (RunSPI(hSpi))
{
bError = FAILED;
}
}
}

when Xcv0 = {&ProBuffer1[0], 4u, NULL, 0u, &RxBuffer1[0], 8u};

result is

when Xcv0 = {&ProBuffer1[0], 4u, NULL, 0u, &RxBuffer1[0], 2u};

result is

thanks

Thread Notes

Parents Reply Children
No Data