Fx3BootAppGcc bootFromSpi()

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

cross mob
lopo_1264666
Level 3
Level 3
25 replies posted 10 replies posted 5 replies posted

I imported this project from "C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\Eclipse\templates\fx3templates".

I2C_BOOT is pretty straightforward and I'm a bit confused about SPI_BOOT.

In bootFromSpi():

(1) Why we need this line of code? It looks like external memory address page boundary alignment but I'm not so sure. Even if this is the case, I thought only write to SPI memory needs page boundary alignment but not for read command.

     bytesToTransfer = bytesToTransfer - (spiAddress % SPI_DMA_XFER_SIZE);

(2) I2C_BOOT didn't check if downloadAddress < CY_FX3_BOOT_ITCM_END but SPI_BOOT did. May I know what is the purpose?

if "(downloadAddress + bytesToTransfer) < CY_FX3_BOOT_ITCM_END", DMA read transfer below will copy data from SPI slave to SPI_DMA_BUF_ADDRESS first before copy over to ITCM. in the else{} statement below, will DMA read transfer overwrite "downloadAddress" straight?

            /* Validate ITCM Memory */

            if ((downloadAddress + bytesToTransfer) < CY_FX3_BOOT_ITCM_END)

            {

                /* Set up the SPI DMA transfer to System Memory */

                status = CyFx3BootSpiDmaXferData (CyTrue, SPI_DMA_BUF_ADDRESS, SPI_DMA_XFER_SIZE, 100);

            }

            else

            {

                /* Set up the SPI DMA transfer to System Memory */

                status = CyFx3BootSpiDmaXferData (CyTrue, downloadAddress, SPI_DMA_XFER_SIZE, 100);

            }

            /* Validate ITCM Memory */

            if ((downloadAddress + bytesToTransfer) < CY_FX3_BOOT_ITCM_END)

            {

                CyFx3BootMemCopy ((uint8_t*)downloadAddress, (uint8_t *)SPI_DMA_BUF_ADDRESS, bytesToTransfer);

            }

0 Likes
1 Solution

EDITTED FOR BETTER CLARITY

Hello,

The following statement:

bytesToTransfer = bytesToTransfer - (spiAddress % SPI_DMA_XFER_SIZE);

is used for making spiAddress a multiple of 64. The page size of the flash used is 256 Bytes. So initially, the spiAddress will be 12. On executing the above instruction, bytesToTransfer is changed to 52. Now after completing first iteration, spiAddress is incremented by 52. This makes spiAddress 64. From this point, bytesToTransfer will remain as 64 itself. So, spiAddress will be incremented in steps of 64 from here. As 64 is a multiple of 256, it ensures that read does not take place from 2 different pages.

Regarding question 2 in the original query,

The function CyFx3BootSpiDmaXferData  uses DMA mode of data transfer. This function will store the data into the address that is passed as the second parameter. Also, it is not possible to use the memory region in the ITCM region as a target for DMA transfers. Hence, the transferred data is stored into a dummy address and later on copied to the downloadAddress using CyFx3BootMemCopy.

Now, the elseif{} statement will write the data obtained directly into downloadAddress. This is possible as this memory region is outside ITCM region. Hence this memory region can be used as a target for DMA transfers.

This implementation is different from I2C boot option. In I2C boot option, we make use of the API CyFx3BootI2cReceiveBytes which makes use of register mode (Non DMA mode) of data transfer. This API returns a pointer of the buffer where data is placed. This pointer is used for copying the buffer contents to the corresponding secAddress.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna

View solution in original post

0 Likes
8 Replies
JayakrishnaT_76
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hello,

Please find my comments to your question 2 in the previous response:

The function CyFx3BootSpiDmaXferData  uses DMA mode of data transfer. This function will store the data into the address that is passed as the second parameter. Also, it is not possible to use the memory region in the ITCM region as a target for DMA transfers. Hence, the transferred data is stored into a dummy address and later on copied to the downloadAddress using CyFx3BootMemCopy.

Now, the elseif{} statement will write the data obtained directly into downloadAddress. This is possible as this memory region is outside ITCM region. Hence this memory region can be used as a target for DMA transfers.

This implementation is different from I2C boot option. In I2C boot option, we make use of the API CyFx3BootI2cReceiveBytes which makes use of register mode (Non DMA mode) of data transfer. This API returns a pointer of the buffer where data is placed. This pointer is used for copying the buffer contents to the corresponding secAddress.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

I too found out that SPI boot has extra lines for CyFx3BootJumpToProgramEntry as compared to I2C boot. Do we need to add this to I2C boot?

0 Likes

I found CyFx3BootJumpToProgramEntry in I2C.

0 Likes

I found the answer for this too:

if ((tmp + gI2cByteAddr) > I2C_SLAVE_SPACE)

tmp = I2C_SLAVE_SPACE - gI2cByteAddr;

0 Likes

Still waiting for your reply on :

bytesToTransfer = bytesToTransfer - (spiAddress % SPI_DMA_XFER_SIZE);

0 Likes

According to your comments for Q2, I think the else{} statement below should change to status = CyFx3BootSpiDmaXferData (CyTrue, downloadAddress, bytesToTransfer, 100) since it writes directly to the system RAM?

/* Invoke the SPI function to do the DMA transfer */

CyFx3BootSpiSetBlockXfer (0, SPI_DMA_XFER_SIZE);

/* Validate ITCM Memory */

if ((downloadAddress + bytesToTransfer) < CY_FX3_BOOT_ITCM_END)

{

/* Set up the SPI DMA transfer to System Memory */

status = CyFx3BootSpiDmaXferData (CyTrue, SPI_DMA_BUF_ADDRESS, SPI_DMA_XFER_SIZE, 100);

}

else

{

/* Set up the SPI DMA transfer to System Memory */

status = CyFx3BootSpiDmaXferData (CyTrue, downloadAddress, SPI_DMA_XFER_SIZE, 100);

}

0 Likes

Hello,

When the API CyFx3BootSpiDmaXferData  is used, the length parameter can be set with any value. But internally, the length parameter is checked to understand if it is a multiple of 16 or not. If it is a multiple of 16, then the same length parameter is used. Otherwise, the length parameter is converted to the next multiple of 16. Due to this, SPI_DMA_XFER_SIZE (64 bytes) is used as the length parameter for the API CyFx3BootSpiDmaXferData.

Even though SPI_DMA_XFER_SIZE is used as length parameter for the API CyFx3BootSpiDmaXferData, the downloadAddress and spiAddress variables are incremented by bytesToTransfer only. So, upon next iteration of the loop, a few bytes (equal to SPI_DMA_XFER_SIZE - bytesToTransfer) will be overwritten from downloadAddress. Hence the result is same as using bytestoTransfer as length for the API CyFx3BootSpiDmaXferData.

Please let me know if you have any queries on this. In the meanwhile, I will get back to you with my comments for the question asked in your response 5.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

EDITTED FOR BETTER CLARITY

Hello,

The following statement:

bytesToTransfer = bytesToTransfer - (spiAddress % SPI_DMA_XFER_SIZE);

is used for making spiAddress a multiple of 64. The page size of the flash used is 256 Bytes. So initially, the spiAddress will be 12. On executing the above instruction, bytesToTransfer is changed to 52. Now after completing first iteration, spiAddress is incremented by 52. This makes spiAddress 64. From this point, bytesToTransfer will remain as 64 itself. So, spiAddress will be incremented in steps of 64 from here. As 64 is a multiple of 256, it ensures that read does not take place from 2 different pages.

Regarding question 2 in the original query,

The function CyFx3BootSpiDmaXferData  uses DMA mode of data transfer. This function will store the data into the address that is passed as the second parameter. Also, it is not possible to use the memory region in the ITCM region as a target for DMA transfers. Hence, the transferred data is stored into a dummy address and later on copied to the downloadAddress using CyFx3BootMemCopy.

Now, the elseif{} statement will write the data obtained directly into downloadAddress. This is possible as this memory region is outside ITCM region. Hence this memory region can be used as a target for DMA transfers.

This implementation is different from I2C boot option. In I2C boot option, we make use of the API CyFx3BootI2cReceiveBytes which makes use of register mode (Non DMA mode) of data transfer. This API returns a pointer of the buffer where data is placed. This pointer is used for copying the buffer contents to the corresponding secAddress.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes