PSOC5LP SPI Interface maximum transfer rate

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
BoKo_4660976
Level 1
Level 1
First like received

Hello to the community,

I'm currently considering using an unit from the PSOC5LP 5800 family as an analog front end (AFE) for my design. As only a limited amount of computation is to be done on the PSOC unit I need a fast enough interface to transfer the sampled signal data off-chip. For the most part the problem I am encountering is that I need to use the SAR-ADC with a 12 bit word at 1MSPS which results in 12Mbps data generation. I would like to transfer this by configuring the PSOC5LP as an 4-wire SPI slave, however all the data sheets I could find about the SPI module on the PSOC5LP state that the maximum transfer rate cannont exceed 5Mbps. In constrast to this, the configuration menu window for the SPI slave module in the PSOC Creator software allows for bit rates of up to 33 Mbps to be set. So my questions are:

What is a reallistic transfer rate that can be achieved with the PSOC5LP 5800 family configured as a spi slave using the spi slave blocks in PSOC Creator?

Is a realization of a SPI slave interface which achieves at least 12Mbps using the UDB-blocks possible?

Can the dedicated USB block somehow be configured as a SPI slave block?

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I tried my usual act then think approach using CY8CKIT-059 (CY8C5888LTI-LP097 on board)

With following schematic.

000-schematic.JPG

I connected

MOSI - MOSI_s

MISO - MISO_s

SCLK - SCLK_s

cs0 - cs_s

externally with jumper wires.

Since you were talking about 12Mbps, I tried with 16Mbps.

So I changed the clock configuration as below.

005-clock.JPG

Then I configured SPIM and SPIS for 16Mbps

002-SPIM.JPG

003-SPIS.JPG

Pins

001-pins.JPG

main.c

==================

#include "project.h"

#include "stdio.h"

#define SPI_BUF_LEN 6

char str[128] ; /* print buffer */

void print(char *str) ;

void init_hardware(void) ;

void splash(void) ;

void dump_data(char *title, uint8_t *data, int num_data) ;

volatile int spis_rcv_flag = 0 ;

volatile int spis_num_rcv = 0 ;

uint8_t tx_buf[SPI_BUF_LEN] = {

    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5

} ;

uint8_t rx_buf[SPI_BUF_LEN] = {

    0u

} ;

CY_ISR(spis_isr)

{

    SPIS_RX_ISR_ClearPending() ;

    spis_rcv_flag = 1 ;

    spis_num_rcv = SPIS_GetRxBufferSize() ;

}

int main(void)

{

    int i ;

    int num_received = 0 ;

 

    init_hardware() ;

 

    splash() ;

    for(;;)

    {

        SPIM_ClearTxBuffer() ;

        SPIS_ClearRxBuffer() ;

     

        dump_data("SPIM Sending:", tx_buf, 6) ;     

        SPIM_PutArray((const uint8_t *)tx_buf, 6) ;

        while(SPIM_GetTxBufferSize()) {

            ;

        }

        while(spis_rcv_flag == 0) {

            ;

        }

        if (spis_rcv_flag) {

            num_received = SPIS_GetRxBufferSize() ;

            for (i = 0 ; i < num_received ; i++ ) {

                rx_buf = SPIS_ReadByte() ;

            }

            dump_data("SPIS Received:", rx_buf, num_received) ;

            print("\n") ;

        }

        CyDelay(2000) ;

    }

}

void print(char *str)

{

    UART_PutString(str) ;

}

void init_hardware(void)

{

    UART_Start() ;

    SPIM_Start() ;

 

    SPIS_ReadStatus() ;

    SPIS_RX_ISR_ClearPending() ;

    SPIS_RX_ISR_StartEx(spis_isr) ;

    SPIS_Start() ;

 

    CyGlobalIntEnable; /* Enable global interrupts. */

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(void)

{

    cls() ;

    sprintf(str, "SPIS Receve Test (%s %s)\n",

        __DATE__, __TIME__) ;

    print(str) ;

}

void dump_data(char *title, uint8_t *data, int num_data)

{

    int i ;

    if ((title != 0) && (*title != 0)) {

        print(title) ;

    }

    for (i = 0 ; i < num_data ; i++ ) {

        sprintf(str, "%02X ", data) ;

        print(str) ;

    }

    print("\n") ;

 

}

==================

Then the serial output was

004-TeraTerm-log.JPG

So I think that although the datasheet states the max as 5Mbps (or 10Mbps),

the device works with 16Mbps.

moto

View solution in original post

5 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I tried my usual act then think approach using CY8CKIT-059 (CY8C5888LTI-LP097 on board)

With following schematic.

000-schematic.JPG

I connected

MOSI - MOSI_s

MISO - MISO_s

SCLK - SCLK_s

cs0 - cs_s

externally with jumper wires.

Since you were talking about 12Mbps, I tried with 16Mbps.

So I changed the clock configuration as below.

005-clock.JPG

Then I configured SPIM and SPIS for 16Mbps

002-SPIM.JPG

003-SPIS.JPG

Pins

001-pins.JPG

main.c

==================

#include "project.h"

#include "stdio.h"

#define SPI_BUF_LEN 6

char str[128] ; /* print buffer */

void print(char *str) ;

void init_hardware(void) ;

void splash(void) ;

void dump_data(char *title, uint8_t *data, int num_data) ;

volatile int spis_rcv_flag = 0 ;

volatile int spis_num_rcv = 0 ;

uint8_t tx_buf[SPI_BUF_LEN] = {

    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5

} ;

uint8_t rx_buf[SPI_BUF_LEN] = {

    0u

} ;

CY_ISR(spis_isr)

{

    SPIS_RX_ISR_ClearPending() ;

    spis_rcv_flag = 1 ;

    spis_num_rcv = SPIS_GetRxBufferSize() ;

}

int main(void)

{

    int i ;

    int num_received = 0 ;

 

    init_hardware() ;

 

    splash() ;

    for(;;)

    {

        SPIM_ClearTxBuffer() ;

        SPIS_ClearRxBuffer() ;

     

        dump_data("SPIM Sending:", tx_buf, 6) ;     

        SPIM_PutArray((const uint8_t *)tx_buf, 6) ;

        while(SPIM_GetTxBufferSize()) {

            ;

        }

        while(spis_rcv_flag == 0) {

            ;

        }

        if (spis_rcv_flag) {

            num_received = SPIS_GetRxBufferSize() ;

            for (i = 0 ; i < num_received ; i++ ) {

                rx_buf = SPIS_ReadByte() ;

            }

            dump_data("SPIS Received:", rx_buf, num_received) ;

            print("\n") ;

        }

        CyDelay(2000) ;

    }

}

void print(char *str)

{

    UART_PutString(str) ;

}

void init_hardware(void)

{

    UART_Start() ;

    SPIM_Start() ;

 

    SPIS_ReadStatus() ;

    SPIS_RX_ISR_ClearPending() ;

    SPIS_RX_ISR_StartEx(spis_isr) ;

    SPIS_Start() ;

 

    CyGlobalIntEnable; /* Enable global interrupts. */

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(void)

{

    cls() ;

    sprintf(str, "SPIS Receve Test (%s %s)\n",

        __DATE__, __TIME__) ;

    print(str) ;

}

void dump_data(char *title, uint8_t *data, int num_data)

{

    int i ;

    if ((title != 0) && (*title != 0)) {

        print(title) ;

    }

    for (i = 0 ; i < num_data ; i++ ) {

        sprintf(str, "%02X ", data) ;

        print(str) ;

    }

    print("\n") ;

 

}

==================

Then the serial output was

004-TeraTerm-log.JPG

So I think that although the datasheet states the max as 5Mbps (or 10Mbps),

the device works with 16Mbps.

moto

Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

BoKo,

What is a realistic transfer rate that can be achieved with the PSOC5LP 5800 family configured as a spi slave using the spi slave blocks in PSOC Creator?

It appears based on a ADC_SAR @ 12 bits (max:18Mbps; 1MSPS),  SPI slave @ 16 bits Config 2 (max:10Mbps) and Digital_out pins (max:33MHz), you're limited to the SPI slave @ 16bits with a maximum transfer rate @ 10Mbps (=0.625 MSPS).

Is a realization of a SPI slave interface which achieves at least 12Mbps using the UDB-blocks possible?

No.  According to the datasheet Config 2 maxes out at 10 MHz.

Can the dedicated USB block somehow be configured as a SPI slave block?

Yes a SPI-S is configurable.  However, I'm assuming the SPI master would be external to the PSoC.  Unless you link the SPI master data requests back to start each ADC conversion the ADC data will be out-of-sync.  The ADC in this mode would be a single conversion per request and the SPI data would always be one ADC sample behind. Request SPI data too fast, you'll get 0s back or too slow you'll get missing ADC data.

If your design is able to handle the PSoC as the SPI master, then 16Mbps is possible.

Len

Len
"Engineering is an Art. The Art of Compromise."
BoKo_4660976
Level 1
Level 1
First like received

Thank you both for your input. I'll post an update if I decide to continue with the PSOC5LP implementation.

odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

BoKo,

Please take a look at this link at Embedded re: using PSoC5 to transfer 12-bit ADC data to PC at 1 Ms/sec

Achieving 1 mega-sample-per-second off of a device - Embedded.com

Also one comment suggests using parallel bus out +FTDI bus reading part. The PSoC5 SAR_ADC has native output bus which allows for direct hardware reading:

https://www.cypress.com/comment/377736#comment-377736

I think the easiest way is to use Cypress FX2LP-base logic analyzer

Cypress EZ-USB FX2LP-based Logic Analyzer using Open Source sigrok PulseView - KBA229176

to read ADC output directly from 12-bit bus using Sigrok s/w. It supports triggered mode, which is eoc output of SAR_ADC. No coding needed!

/odissey1

MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi, /odissy1-san,

I laughed at the line ...

> However, we could taste blood, so we kept going.

moto

0 Likes