8 Replies Latest reply on Apr 4, 2018 9:08 PM by user_483038750

    PSoC4 SPI master RX interrupt setting with API

    user_483038750

      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

        • 1. Re: PSoC4 SPI master RX interrupt setting with API
          user_1377889

          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

          • 2. Re: PSoC4 SPI master RX interrupt setting with API
            user_483038750

            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.

            • 3. Re: PSoC4 SPI master RX interrupt setting with API
              user_483038750

              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

              • 4. Re: PSoC4 SPI master RX interrupt setting with API
                user_483038750

                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

                • 5. Re: PSoC4 SPI master RX interrupt setting with API
                  user_483038750

                  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

                  • 6. Re: PSoC4 SPI master RX interrupt setting with API
                    user_483038750

                    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  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[i]));   

                        }

                       

                        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

                    • 7. Re: PSoC4 SPI master RX interrupt setting with API
                      user_483038750

                      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

                      • 8. Re: PSoC4 SPI master RX interrupt setting with API
                        user_483038750

                        Hi,

                        I am sorry that I forgot to attach the waveform of the polling.

                         

                        In case of all polling

                         

                        Best regards,

                        Yocchi