PDL API's for SPI implementation

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

cross mob
BiM_4640481
Level 4
Level 4
25 replies posted 25 sign-ins 10 replies posted

Hello, 

My project requires to use Toshiba NAND flash instead of the QSPI NOR flash. So I have to integrate Toshiba flash driver to Bootloader code which can be done only via PDL API’s. I have already raised a query in discussion forum and I think you are the person who guided me to use PDL layer.

In order to get it work I tried to port the SPI master example with PDL API’s. Sending data from master to slave is successful. But when I send it from slave to master, the data received in master is 0xFF. I used Port 12 as master and port 10 as slave and shorted these lines on EVB PSoC6 -43012.

 

Also in my  actual requirement I have to use P11_1 as chip select for master, and P12 pins for MISO, MOSI and SCLK for master. Is this feasible?

 

Your inputs will be of great help.

0 Likes
1 Solution

Hello,

The detailed explanation in this link solved the issue

Re: SCB SPI transmit and receive buffer size

 

Thanks,

Binsy M S

View solution in original post

0 Likes
8 Replies
ShipingW_81
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 replies posted

There is demo project for SPI usage with ModusToolbox PSoC 6 SDK - https://github.com/cypresssemiconductorco/mtb-example-psoc6-spi-master

The SPI host and slave on the same device.

Have you ever tried it?

0 Likes

Yes. This works with HAL API's. 

HAL API,s cannot be used at bootloader level. Instead PDL APIs are required. 

CAn you please provide the same SPI master example using PDL API's?

 

Thanks,

Binsy M S

0 Likes

This one uses the PDL API - https://github.com/cypresssemiconductorco/mtb-example-psoc6-spi-master-dma

Let me know if it meet your requirement.

0 Likes

No. I dont want to use DMA. 

In SPI master example, I need to used PDL PAI's instead of HAL API's.

 

Thanks,

Binsy M S

0 Likes
ShipingW_81
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 replies posted

The PDL API documentation might be helpful to setup a demo using SPI PDL API  -https://cypresssemiconductorco.github.io/psoc6pdl/pdl_api_reference_manual/html/group__group__scb__s...

0 Likes

Yes. I referred this link and tried with PDL API's.  I used Port 12 as master and port 10 as slave. Data send from master to slave is received correctly. But that send from slave to master is not received correctly. Below is the code i used. Can you please suggest the places I have to make the changes to get it work

Below are the macros used:

/*************PDL*****************/
/* Allocate context for SPI operation */
cy_stc_scb_spi_context_t spiContext;
/* Slave configuration */
cy_stc_scb_spi_config_t spiConfig_slave =
{
.spiMode = CY_SCB_SPI_SLAVE,
.subMode = CY_SCB_SPI_MOTOROLA,
.sclkMode = CY_SCB_SPI_CPHA0_CPOL0,
.oversample = 0UL,
.rxDataWidth = 8UL,
.txDataWidth = 8UL,
.enableMsbFirst = false,
.enableInputFilter = false,
.enableFreeRunSclk = false,
.enableMisoLateSample = false,
.enableTransferSeperation = false,
.ssPolarity = CY_SCB_SPI_ACTIVE_LOW,
.enableWakeFromSleep = false,
.rxFifoTriggerLevel = 0UL,
.rxFifoIntEnableMask = 0UL,
.txFifoTriggerLevel = 0UL,
.txFifoIntEnableMask = 0UL,
.masterSlaveIntEnableMask = 0UL,
};

/* Master configuration */
cy_stc_scb_spi_config_t spiConfig_master =
{
.spiMode = CY_SCB_SPI_MASTER,
.subMode = CY_SCB_SPI_MOTOROLA,
.sclkMode = CY_SCB_SPI_CPHA0_CPOL0,
.oversample = 10UL,
.rxDataWidth = 8UL,
.txDataWidth = 8UL,
.enableMsbFirst = false,
.enableInputFilter = false,
.enableFreeRunSclk = false,
.enableMisoLateSample = true,
.enableTransferSeperation = false,
.ssPolarity = CY_SCB_SPI_ACTIVE_LOW,
.enableWakeFromSleep = false,
.rxFifoTriggerLevel = 0UL,
.rxFifoIntEnableMask = 0UL,
.txFifoTriggerLevel = 0UL,
.txFifoIntEnableMask = 0UL,
.masterSlaveIntEnableMask = 0UL,
};
GPIO_PRT_Type *Port_1 = GPIO_PRT1;
GPIO_PRT_Type *Port_12 = GPIO_PRT12;
GPIO_PRT_Type *Port_10 = GPIO_PRT10;
GPIO_PRT_Type *Port_5 = GPIO_PRT5;


/* Assign pins for SPI master on SCB6: P12[0], P12[1], P12[2] and P12[3] */
#define SPI_PORT_MASTER P12_0_PORT
#define SPI_MISO_NUM_MASTER P12_1_NUM
#define SPI_MOSI_NUM_MASTER P12_0_NUM
#define SPI_SCLK_NUM_MASTER P12_2_NUM
#define SPI_SS_NUM_MASTER P12_3_NUM

/* Assign pins for SPI slave on SCB1: P10[0], P10[1], P10[2] and P10[3] */
#define SPI_PORT_SLAVE P10_0_PORT
#define SPI_MISO_NUM_SLAVE P10_1_NUM
#define SPI_MOSI_NUM_SLAVE P10_0_NUM
#define SPI_SCLK_NUM_SLAVE P10_2_NUM
#define SPI_SS_NUM_SLAVE P10_3_NUM

/* Assign divider type and number for SPI */
#define SPI_CLK_DIV_TYPE (CY_SYSCLK_DIV_8_BIT)
#define SPI_CLK_DIV_NUM (0U)
#define SPI_CLK_DIV_NUMBER_MASTER 5
#define SPI_CLK_DIV_NUMBER_SLAVE 5

Following is the settings for master

cy_en_scb_spi_status_t ret;
ret = Cy_SCB_SPI_Init(SCB6, &spiConfig_master, &spiContext);
if(ret == CY_SCB_SPI_SUCCESS)
{
printf("Cy_SCB_SPI_Init of master success\r\n");
}
else
{
printf("Cy_SCB_SPI_Init of master failed\n");
}

/* Connect SCB6 SPI function to pins */
Cy_GPIO_SetHSIOM(SPI_PORT_MASTER, SPI_MISO_NUM_MASTER, P12_1_SCB6_SPI_MISO);
Cy_GPIO_SetHSIOM(SPI_PORT_MASTER, SPI_MOSI_NUM_MASTER, P12_0_SCB6_SPI_MOSI);
Cy_GPIO_SetHSIOM(SPI_PORT_MASTER, SPI_SCLK_NUM_MASTER, P12_2_SCB6_SPI_CLK);
Cy_GPIO_SetHSIOM(SPI_PORT_MASTER, SPI_SS_NUM_MASTER, P12_3_SCB6_SPI_SELECT0 );
//Cy_GPIO_SetHSIOM(P5_0_PORT, P5_1_NUM, P5_0_GPIO);

/* Configure SCB6 pins for SPI Master operation */
Cy_GPIO_SetDrivemode(SPI_PORT_MASTER, SPI_MISO_NUM_MASTER, CY_GPIO_DM_HIGHZ);
Cy_GPIO_SetDrivemode(SPI_PORT_MASTER, SPI_MOSI_NUM_MASTER, CY_GPIO_DM_STRONG_IN_OFF);
Cy_GPIO_SetDrivemode(SPI_PORT_MASTER, SPI_SCLK_NUM_MASTER, CY_GPIO_DM_STRONG_IN_OFF);
Cy_GPIO_SetDrivemode(SPI_PORT_MASTER, SPI_SS_NUM_MASTER, CY_GPIO_DM_STRONG_IN_OFF);

/* Connect assigned divider to be a clock source for SPI */
Cy_SysClk_PeriphAssignDivider(PCLK_SCB6_CLOCK, SPI_CLK_DIV_TYPE, SPI_CLK_DIV_NUM);

/* SPI master desired data rate is 1 Mbps.
* The SPI master data rate = (clk_scb / Oversample).
* For clk_peri = 50 MHz, select divider value 5 and get SCB clock = (50 MHz / 5) = 10 MHz.
* Select Oversample = 10. These setting results SPI data rate = 10 MHz / 10 = 1 Mbps.
*/
Cy_SysClk_PeriphSetDivider (SPI_CLK_DIV_TYPE, SPI_CLK_DIV_NUMBER_MASTER, 4UL);
Cy_SysClk_PeriphEnableDivider(SPI_CLK_DIV_TYPE, SPI_CLK_DIV_NUMBER_MASTER);

/* Enable SPI to operate */
Cy_SCB_SPI_Enable(SCB6);

/******************************************************************************************/

Following are the settings for slave:

/* slave */
cy_en_scb_spi_status_t ret1;
ret1 = Cy_SCB_SPI_Init(SCB1, &spiConfig_slave, &spiContext);
if(ret1 == CY_SCB_SPI_SUCCESS)
{
printf("Cy_SCB_SPI_Init of slave success\r\n");
}
else
{
printf("Cy_SCB_SPI_Init of slave failed\n");
}

/* Connect SCB1 SPI function to pins */
Cy_GPIO_SetHSIOM(SPI_PORT_SLAVE, SPI_MISO_NUM_SLAVE, P10_1_SCB1_SPI_MISO);
Cy_GPIO_SetHSIOM(SPI_PORT_SLAVE, SPI_MOSI_NUM_SLAVE, P10_0_SCB1_SPI_MOSI);
Cy_GPIO_SetHSIOM(SPI_PORT_SLAVE, SPI_SCLK_NUM_SLAVE, P10_2_SCB1_SPI_CLK );
Cy_GPIO_SetHSIOM(SPI_PORT_SLAVE, SPI_SS_NUM_SLAVE, P10_3_SCB1_SPI_SELECT0);

/* Configure SCB1 pins for SPI Slave operation */
Cy_GPIO_SetDrivemode(SPI_PORT_SLAVE, SPI_MISO_NUM_SLAVE, CY_GPIO_DM_STRONG_IN_OFF);
Cy_GPIO_SetDrivemode(SPI_PORT_SLAVE, SPI_MOSI_NUM_SLAVE, CY_GPIO_DM_HIGHZ);
Cy_GPIO_SetDrivemode(SPI_PORT_SLAVE, SPI_SCLK_NUM_SLAVE, CY_GPIO_DM_HIGHZ);
Cy_GPIO_SetDrivemode(SPI_PORT_SLAVE, SPI_SS_NUM_SLAVE, CY_GPIO_DM_HIGHZ);

/* Connect assigned divider to be a clock source for SPI */
Cy_SysClk_PeriphAssignDivider(PCLK_SCB1_CLOCK, SPI_CLK_DIV_TYPE, SPI_CLK_DIV_NUM);

/* SPI data rate is defined by the SPI master because it drives SCLK.
* This clk_scb enables SPI slave operate up to maximum supported data rate.
* For clk_peri = 50 MHz, select divider value 1 and get clk_scb = (50 MHz / 1) = 50 MHz.
*/
Cy_SysClk_PeriphSetDivider (SPI_CLK_DIV_TYPE, SPI_CLK_DIV_NUMBER_SLAVE, 0UL);
Cy_SysClk_PeriphEnableDivider(SPI_CLK_DIV_TYPE, SPI_CLK_DIV_NUMBER_SLAVE);

/* Enable SPI to operate */
Cy_SCB_SPI_Enable(SCB1);

/*************************************************************************************/

Following is the code for data send and receive

/* Enable interrupts */
__enable_irq();

ret = Cy_SCB_SPI_Write(SCB6,0x9F);

int val = Cy_SCB_SPI_Read(SCB1);
printf("Command received in slave%0x\r\n", val);

Now the slave sends 0x96 to master

ret = Cy_SCB_SPI_Write(SCB1,0x96);

int val = Cy_SCB_SPI_Read(SCB6);
printf("Command received in master %0x\r\n", val);

Is there any other settings we have to do for SPI communication? 

Your inputs will be of great help

 

Thanks,

Binsy M S

0 Likes
ShipingW_81
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 replies posted

You can refer to a SPI code example designed for PSoC Creator for how to read data from slave end. The APIs is same with Modus Toolbox.

Project "Low_Level_Polling_Master" from link - https://www.cypress.com/documentation/code-examples/ce221120-psoc-6-mcu-spi-master

0 Likes

Hello,

The detailed explanation in this link solved the issue

Re: SCB SPI transmit and receive buffer size

 

Thanks,

Binsy M S

0 Likes