- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am trying the SPI master RX interrupt setting with API.
At first, RX interrupt is not enabled.
Then, in the main I would like to enable "RX FIFO full(SPIMH_INTR_RX_FULL)" interrupt after sending the Opcode + 15-bit Address data like below.
I could recieve Data when "RX_NOT_EMPTY(SPIMH_INTR_RX_NOT_EMPTY)" was set. but in case of "RX FIFO full" I won't recieve.
Opcode and Address were sent and the interrupt was occurred. But there is no data in the RX FIFO. Maybe the data receive setting was not allowed.
What is wrong?
------------------------------ main.c ------------------------------
Pin_FRAMCS_Write(0);
// Send F-RAM Read Command
SPIMH_SpiUartWriteTxData(FRAM_SRAM_READ_CMD);
// For densities greater than or equal to 1MBit, send 3 byte address
if(FRAM_SPI_spi_density >= SPI_1MBit)
{
SPIMH_SpiUartWriteTxData(MSB_ADDR_BYTE(addr));
}
// Send 2 address bytes
SPIMH_SpiUartWriteTxData(ISB_ADDR_BYTE(addr));
SPIMH_SpiUartWriteTxData(LSB_ADDR_BYTE(addr));
// Wait for the transmission to complete
while(0 != (SPIMH_SpiUartGetTxBufferSize() | SPIMH_SpiIsBusBusy()))
{
}
// Clear the receive buffer
SPIMH_SpiUartClearRxBuffer();
SPIMH_ClearRxInterruptSource(SPIMH_INTR_RX_FULL);
SPIMH_SetRxInterrupt(SPIMH_INTR_RX_FULL);
SPIMH_SetRxInterruptMode(SPIMH_INTR_RX_FULL);
// Read data bytes from F-RAM
i = 0;
while(i != total_data_count)
{
// Send dummy byte to receive data
if((SPIMH_TX_FIFO_STATUS_REG & 0x0F)<6)
{
SPIMH_SpiUartWriteTxData(dummy_data); // receive clock generation by using dummy data write
i++;
}
}
while(g_spi_rx_cnt != total_data_count)
{
}
while(0 != SPIMH_SpiIsBusBusy())
{}
// De-select F-RAM device
Pin_FRAMCS_Write(1);
Best regards,
Yocchi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I cannot see an interrupt handler in your code snippet nor a ist_SPI_RX_StartEx(InterruptHandler).
I would recommend to set the SPI Byte mode and increase the buffers to 16.
When still got stuck, can you please post your complete project so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Bob,
I attached the project file.
I prepared both "SPIMH_INTR_RX_NOT_EMPTY" and "SPIMH_INTR_RX_FIFO_LEVEL" interrupt instead of "SPIMH_INTR_RX_FULL".
The project are not necessarily "SPIMH_INTR_RX_FULL".
"SPIMH_INTR_RX_NOT_EMPTY" and "SPIMH_INTR_RX_FIFO_LEVEL" are same behavior because SPIMH_SetRxFifoLevel is set to 1.
"SPIMH_INTR_RX_NOT_EMPTY" runs well but "SPIMH_INTR_RX_FIFO_LEVEL" does not run well.
If you set "#define rx_not_empty" in FRAM_SPI.h, "SPIMH_INTR_RX_NOT_EMPTY" interrupt is set. On the other hand, if you comment out it "SPIMH_INTR_RX_FIFO_LEVEL" interrupt is set.
the codes is changed in FRAM_SPI.c below. and I think that SPIMH_SetRxInterrupt and SPIMH_SetRxInterruptMode are allowed interrupt.
#if defined(rx_not_empty)
SPIMH_SetRxInterrupt(SPIMH_INTR_RX_NOT_EMPTY); //##
SPIMH_SetRxInterruptMode(SPIMH_INTR_RX_NOT_EMPTY); //##
#else
SPIMH_SetRxFifoLevel (rx_fifo_level);
SPIMH_SetRxInterrupt(SPIMH_INTR_RX_FIFO_LEVEL); //##
SPIMH_SetRxInterruptMode(SPIMH_INTR_RX_FIFO_LEVEL); //##
temp = SPIMH_GetRxInterruptSource();
temp = SPIMH_SpiUartGetRxBufferSize();
#endif
I am using CY8CKIT-044 and CY15FRAMKIT-001.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Bob,
I had a mistake in CY_ISR(isr_SPI_RX_CustomInterrupt).
and I am trying "SPIMH_INTR_RX_FIFO_LEVEL" interrupt.
Please correct it below.
#if defined(rx_not_empty)
SPIMH_ClearRxInterruptSource(SPIMH_INTR_RX_NOT_EMPTY);
#else
SPIMH_ClearRxInterruptSource(SPIMH_INTR_RX_FIFO_LEVEL);
#endif
Best regards,
Yocchi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I can finally run well with the RX FIFO Level.
I would like to confirm two settinigs.
Are they right?
1. Should I set the RX FIFO Level to 0 If I want to generate an interrupt when receiving 1 byte
(RX data bits = 8 in the configuration of SPI) data?
2. May I set SPIMH_SetRxInterruptMode() function to enable and disable the RX FIFO Level interrupt?
[when enabling the RX FIFO Level interrupt]
SPIMH_SetRxInterruptMode(SPIMH_INTR_RX_FIFO_LEVEL);
[when disabling the RX FIFO Level interrupt]
SPIMH_SetRxInterruptMode(SPIMH_INTR_RX_BLOCKED);
Best regards,
Yocchi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I measured both "in case of enabling RX FIFO level interrupt with SPI master configuration" and "in case of enabling RX FIFO level interrupt after writing the memory address with API" the execution time. It was improved from 171.68us to 111.77us.
in case of enabling RX FIFO level interrupt with SPI master configuration
in case of enabling RX FIFO level interrupt after address write with API
Best regards,
Yocchi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I noticed that it takes up to 2 SCLK clocks between TX FIFO empty and slave select assertion.
Please see the SCB Component Datasheet in the description of uint32 SCB_SpiIsBusBusy(void).
And refer to Re: SPI using PSoC 4 SCB 4.0 .
SPI Master does not assign slave select line immediately after the first word is written
into TX FIFO. It takes up to 2 SCLK clocks to assign slave select. Until this happens the
bus considered not busy.
Well, If we send the data after opcode and address with the burst mode, we can not check "while (SPI_SpiUartGetRxBufferSize() == 0) { } "
like Re: SPI using PSoC 4 SCB 4.0.
In case of enabling RX FIFO level interrupt with SPI master configuration, we can check the
counts that received dummy send data in RX interrupt handler. but wasting time.
In case of polling, I think that we can wait up to 2 SCLK clocks like below.
/* Workaround because taking up to 2 SCLK clocks to assign slave select after writing TX FIFO */
#define txfifo2busbusy (uint16)((((((uint32)SPIMH_SCBCLK_DIV_REG & SPIMH_SCBCLK_DIV_INT_MASK) >> SPIMH_SCBCLK_DIV_INT_SHIFT)+1)*1000000*(2)*SPIMH_SPI_OVS_FACTOR/CYDEV_BCLK__HFCLK__MHZ+999999)/1000000)
uint8 FRAM_SPI_BurstWrite ( uint32 addr, uint8 *data_write_ptr, uint32 total_data_count )
{
...
/* Send data byte */
SPIMH_SpiUartWriteTxData((uint8)(data_write_ptr));
}
while(0 != SPIMH_SpiUartGetTxBufferSize())
{}
/* Workaround because taking up to 2 SCLK clocks to assign slave select after writing TX FIFO */
CyDelayUs(txfifo2busbusy);
while(0 != SPIMH_SpiIsBusBusy())
{}
/* De-select the F-RAM device */
Pin_FRAMCS_Write(1);
/* return the communication status */
return SPI_COM_SUCCESS;
}
But I think that these conditions must be kept.
1. only Motorola and National Semiconductor sub-modes
2. TX buffer size is less than the TX FIFO depth(not use Software Buffer)
3. Don't use clock from terminal in SCB configuration
Best regards,
Yocchi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I measured each access time.
access time =
Slave Select (SS) enable => WREN => WRITE => WRDI => READ => Slave Select (SS) disable
In case of all polling
in case of enabling RX FIFO level interrupt after address write with API
in case of enabling RX FIFO level interrupt with SPI master configuration
Best regards,
Yocchi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am sorry that I forgot to attach the waveform of the polling.
In case of all polling
Best regards,
Yocchi