1 2 Previous Next 18 Replies Latest reply on Mar 17, 2020 7:17 PM by AlVy_2459421

    Re: CY8CPROTO-062-4343w SD card


      Hello RoDu_4468516,


      The resistor R62 is not populated by default in the CY8CPROTO-062-4343W Kit. So, pin P12_1 cannot be used as the Card Detect pin. Maybe that is where you are getting stuck.


      I created a quick project to use the SDHC block of CY8CPROTO-062-4343W board. The project writes a block of data into the SD Card and then reads it back. Please let me know if this is helpful.


      Thanks and Regards,

      Rakshith M B

        • 1. Re: CY8CPROTO-062-4343w SD card

          Hi  RakshithM,

          great thanks!

          The coder works as it should. However, the maximal block size that the library allows to transmit at once is 64 Kbytes. Perhaps, one can switch from DMA to DMAC in the library to remove this limitation, as it seems to be the limitation of used DMA and not of SD standard. Am I right? Another limitation that I have found seems more critical. Current example works at SD clock 25 MHz that brings theoretical limit of bandwidth 12.5 MBps. However, I have found that with 53248 byte blocks and 100MHz at DMA controller and processor cores the baud rate can be 7.64 MBps. This is not bad, but more is better. To increase baud rate I increased clock from 25 MHz to 50 MHz. To do this I changed the divider in the configurator of the clock that goes to SDIO1 to have 100 MHz instead of 50 MHz in your example. However, this was not sufficient and I introduced the following code after SDIO initialization but before memory writing command:



                      //CY_SD_HOST_BUS_SPEED_SDR50 -> 100MHz - works with 3V3 and 1.8V IO in Modus 1.1 with one sector transfer

                      //CY_SD_HOST_BUS_SPEED_SDR25 -> 50MHz - works here

          Cy_SD_Host_SdCardChangeClock(SDHC1, CY_SD_HOST_CLK_50M);                            //this is needed - works without previous settings

                                                                     //at 25M and 50M, but does not work with 100M, also with previous line here

          Cy_SysLib_Delay(1/*msec*/); //my addition


          To make these functions working I overridden one of them in the beginning and introduced one fake variable:


          cy_stc_sd_host_context_t sdHostContext;



          * Function Name: Cy_SD_Host_SdCardChangeClock



          *  Changes the Host controller SD clock.


          * \param *base

          *     The SD host registers structure pointer.


          * \param frequency

          *     The frequency in Hz.


          * \return \ref cy_en_sd_host_status_t



          static cy_en_sd_host_status_t Cy_SD_Host_SdCardChangeClock(SDHC_Type *base, uint32_t frequency)


              cy_en_sd_host_status_t ret = CY_SD_HOST_ERROR_INVALID_PARAMETER;

              uint32_t               clkDiv;

              uint32_t               clockInput = 100000000;//CY_SD_HOST_PERI_FREQUENCY;


              //CY_ASSERT_L2(CY_SD_HOST_IS_FREQ_VALID(frequency)); //not needed?


              if (NULL != base)


                  clkDiv = (clockInput / frequency) >> 1UL;


                  ret = Cy_SD_Host_SetSdClkDiv(base, (uint16_t)clkDiv);




              return ret;



          This addition indeed increased clock from 25 to 50 MHz. This was checked by oscilloscope.

          The data rate of mentioned above packets also increased up to 10.71 MBps. This is not bad, but shows existence of essential time loss for each 53248 byte data packet while its transmission time 4.97 ms can be considered as 2.15 ms of "pure" transmission time at 25MBps + 2.82 ms of wasted time because of some overhead. This is basically the reason why it may be beneficial to switch to larger packets.

          However, the main my problem was that when I tried to switch to 100 MHz clock by the command

          Cy_SD_Host_SdCardChangeClock(SDHC1, CY_SD_HOST_CLK_100M); 

          writing to SD card was blocked. I could see 100MHz clock by oscilloscope, but this example did not work. Thus, any hint what should be changed can be helpful. Perhaps, some part of my added code does not work as expected (i.e.


          I would like to note that similar (but slightly different) code in ModusToolbox 1.1 allows to read/write one sector (512 bytes) at 100 MHz clock using the same hardware, but there is some other omission that did not allow to read/write several sectors at once.

          I plan to take a look at both my codes in Modus 1.1 and 2.0, but if you have an idea how to run your example at 100MHz clock, this would be very helpful.

          • 2. Re: CY8CPROTO-062-4343w SD card

            Hello RakshithM


            Thank you so much for the example!  Occasionally when I'm doing a large number of consecutive writes, I start getting nonzero return codes. 


            Using the macros:


            result = cyhal_sdhc_write(&_sdhc_object, a, (uint8_t*)b, &block_count);

            if(result != 0) {

                uint8_t type = CY_RSLT_GET_TYPE(result);

                uint16_t module_id = CY_RSLT_GET_MODULE(result);

                uint16_t error_code = CY_RSLT_GET_CODE(result);

                printf("blocks written: %u, type %u, module %u, %u \n", block_count, module_id, error_code);



            I end up with the following:

            type 0, module 2, error_code 134231568


            Does anyone have any idea what could be causing this?  It seems to be occurring randomly.


            Thanks again

            • 3. Re: CY8CPROTO-062-4343w SD card

              Hi RoDu,


              I have a guess that SD card may need some time for processing commands and when the next command is coming, it may be busy and can't respond, or responds with an unexpected format. As a quick hack you can try to introduce delays between commands just for testing purposes. Another idea is to wrap a writing command into a cycle: do counter++; {write command} while (bad response && counter<counterMax). Another way is to find in SD documentation how to check card ready status and poll it in a loop before each writing command.


              Hope this can help. It would be nice if you could give a feedback what fixed this problem for you.



              • 4. Re: CY8CPROTO-062-4343w SD card

                I would like to correct my previous comments.

                SDHC has its own DMA engine. It has no relation to mentioned DMA and DMAC general-purpose controllers.

                Why this example did not work in my hands with blocks above 64 Kbytes, I don't know.

                However, I patched my old code in Modus 1.1 environment. I tested blocks as large as 384 KBytes without any issues.

                Transmission of one such block with 100 MHz SD clock took 12 ms.

                Thus, sustained data rate was 32.768 MBps. This is not bad.

                Interestingly to note, testing of Octal SPI data rate at 50 MHz clock and DMAC gave a very similar value 32.576 MBps.

                However, the block size was much smaller - 12900 bytes.


                Please let me know if you know how to get higher data rates at SDHC or Octal SPI.


                Good luck with coding!



                • 5. Re: CY8CPROTO-062-4343w SD card



                  I thought the same as you but I tried putting a




                       Cy_SysLib_Delay(1000);   //might as well start large



                  After every one of my reads and writes.  Now instead of failed reads and writes I end up with randomly occurring never ending loops where that function never resolves to false.

                  • 6. Re: CY8CPROTO-062-4343w SD card

                    Hi AlVy_2459421, RoDu_4468516,


                    Thank you for your valuable inputs.


                    RoDu_4468516, Can you please share your project? I was unable to reproduce your issue. I was able to write 51200 bytes without any issue or data loss. Also, cyhal_sdhc_is_busy(sdhc_obj) is not necessary.This function is useful on an async call to wait for the transaction to complete.



                    In the PSoC 6 MCU: CY8C62x8, CY8C62xA Architecture TRM, it is mentioned that SDHC supports only 50 MHz at 3.3 V signalling. I was also able to change the clock speed only upto 50 MHz (after changing the clock divider to 1 in Device Configurator). Can you please share the code that you used to change the clock to 100 MHz? Also, SDHC supports only 4-bit bus interface.


                    Thanks and Regards,

                    Rakshith M B


                    • 7. Re: CY8CPROTO-062-4343w SD card

                      Hi Rakshith,


                      thank you for your reply and 50 MHz mode testing. Indeed, in accordance with SD specification, high baud rates need 1.8V IO supply. However, as I noted in the attached PDF file, 100 MHz mode can work at 3.3V, although this is out of specification. Indeed, I run all my tests at modified board. Modifications are described in the file attached.

                      I plan to check that my code works fine with the original board, and than I shall share it.


                      Yes, Cypress SDHC supports only 4-bit bus. I used Octal SPI to connect FPGA that provided a test signal.


                      In the very last technical processor specification SDHC speed is limited by 80MHz, whereas in the original release is was 100MHz.

                      Perhaps, there is sense in this, because if SDHC limits data rate internally at about 32.768MBps, both 80 and 100 MHz clock modes will have identical data rate at the end limited by SDHC internal architecture. However, 32.768MBps limit is my measure, it was not declared officially. May be, the speed limit can be lifted by switching from SDMA to ADMA, but I did not test this. I used SDMA only.


                      With best regards,



                      1 of 1 people found this helpful
                      • 8. Re: CY8CPROTO-062-4343w SD card

                        Hi Rakshith,


                        finally, I have tested my code with the original non-modified CY8CPROTO-062-4343W.

                        It works. The attached project is done in Modus 1.1.

                        When the program starts with the inserted memory card, the following information is displayed in the

                        terminal window (115200 bps, 8-n-1):

                        "UART initialization complete


                        SDHC 100MHz code example started


                        Here 1MB = 1,000,000 bytes


                        Random values to put in the first sectors of two 384*1024-byte blocks: 49 15


                        Write duration of 384*1024-byte blocks in microseconds: 13032 12037

                        Write data rates:  30.173 32.667 MBps

                        Mean+/-Std:  31.420+/-1.764 MBps


                        Read duration of 384*1024-byte blocks in microseconds: 8787 8785

                        Read data rates:  44.750 44.760 MBps

                        Mean+/-Std:  44.755+/-0.007 MBps


                        SD Write/Read OK"


                        Now I shall give some explanations.

                        The program writes two 384*1024-byte blocks one after another starting from zero sector of SD card

                        inserted in SDHC1. Then, the program reads these two blocks and checks that they are OK.

                        True random number generator is used to generate starting values that are written in the first sectors

                        of the first and the second blocks respectively. One value is written in all 512 bytes of one sector. Values

                        are incremented by 1 at each sector (with return to 0 after 255).

                        To measure duration of operations 32-bit timer is clocked by 1MHz signal to get 1 us accuracy.

                        As it is seen, writing speed was about 31.420 MBps and reading speed - 44.755 MBps.

                        Interestingly, reading speed is close to theoretical maximum at 100 MHz, i.e. 50 MBps.

                        Thus, having 100MHz clock has some advantage, for instance, against 80 MHz clock.


                        Now about problems and non-fixed issues of the attached code:

                        1. MicroSD card compatibility. The code was tested with Samsung Evo Plus 128GB memory card

                          (white-red color). However, there were some problems with Lexar 633x 32GB memory card

                          (black-blue color). Thus, it seems to be that there are some omissions in the code.

                        2. Necessity to re-initialize memory card after 384*1024-byte block operation.

                            It has been found that the second block is not written properly if the card is not initialized the second

                            time after the first block. This is a big issue that should be solved. Initialization of the card requires

                            very significant time and it should be done only once at the beginning, and not after each operation.

                            Now card re-initialization looks like:


                        Cy_SD_Host_InitCard(SDHC1, &SDHC1_card_cfg, &sdHostContext);


                        Cy_SD_Host_SdCardChangeClock(SDHC1, CY_SD_HOST_CLK_100M);


                        As you can see, the attached code is not polished. It should be improved to be practically useful.

                        If you shall test this code, please let me know with what types of memory cards it works, and with what does not.

                        Ideas directed towards elimination of memory card re-initialization are also very welcome.


                        Interestingly, but Modus 2.0 code uploaded by you does not have issues (1) and (2). One can write one 64K block after

                        another, and read both blocks without SD card re-initialization. However, the unpleasant restrains are: 50MHz

                        bus frequency limit, and 64K block size limit. Both restrains drastically decrease throughput.


                        With best regards,



                        1 of 1 people found this helpful
                        • 9. Re: CY8CPROTO-062-4343w SD card

                          Just for comparison, SDHC rates  obtained with Modus 2.0, 64K block, 50MHz bus (25 MBps peak throughput):


                          Starting write the 1st 64K block

                          Duration: 5016 us, Data rate: 13.065 MBps


                          Starting write the 2nd 64K block

                          Duration: 5015 us, Data rate: 13.068 MBps


                          Starting read the 1st 64K block

                          Duration: 3514 us, Data rate: 18.650 MBps


                          Starting read the 2nd 64K block

                          Duration: 3515 us, Data rate: 18.645 MBps


                          With best regards,



                          1 of 1 people found this helpful
                          • 10. Re: CY8CPROTO-062-4343w SD card

                            Hi Rakshith,


                            It has happened that activation of 100MHz mode of SDHC in Modus 2.0 is very easy to do.

                            The singe thing that was needed is selection of low voltage signaling in configuration:

                            const cyhal_sdhc_config_t sdhc_config = {false, true, false, 4};    //the second - low voltage signaling.

                            However, physical powering of IO by 1.8V is not necessary. Just the driver should "know" that

                            low voltage signaling is allowed.


                            Thus, the whole SDHC configuration looks as:


                            const cyhal_sdhc_config_t sdhc_config = {false, true, false, 4};    //the second - low voltage signaling.

                            rslt = cyhal_sdhc_init(&sdhc_obj, &sdhc_config, cmd, clk, dat0, dat1, dat2, dat3, dat4, dat5, dat6, dat7, card_detect, io_volt_sel,                                                                  card_if_pwren, card_mech_writeprot, led_ctl, emmc_reset);


                            Cy_SD_Host_SdCardChangeClock(SDHC1, CY_SD_HOST_CLK_100M);  


                            I modified your example by adding writing/reading of two 64KB blocks with timing.

                            Now the program output looks as:


                            Starting write the 1st 64K block

                            Duration: 3515 us, Data rate: 18.645 MBps


                            Starting write the 2nd 64K block

                            Duration: 3515 us, Data rate: 18.645 MBps


                            Starting read the 1st 64K block

                            Duration: 2013 us, Data rate: 32.556 MBps


                            Read_buff value in 0 = 7

                            Read_buff value in 5120 = 7

                            Read_buff value in 10240 = 7

                            Read_buff value in 15360 = 7

                            Read_buff value in 20480 = 7

                            Read_buff value in 25600 = 7

                            Read_buff value in 30720 = 7

                            Read_buff value in 35840 = 7

                            Read_buff value in 40960 = 7

                            Read_buff value in 46080 = 7

                            Read_buff value in 51200 = 7

                            Read_buff value in 56320 = 7

                            Read_buff value in 61440 = 7


                            Starting read the 2nd 64K block

                            Duration: 2013 us, Data rate: 32.556 MBps


                            Read_buff value in 0 = 8

                            Read_buff value in 5120 = 8

                            Read_buff value in 10240 = 8

                            Read_buff value in 15360 = 8

                            Read_buff value in 20480 = 8

                            Read_buff value in 25600 = 8

                            Read_buff value in 30720 = 8

                            Read_buff value in 35840 = 8

                            Read_buff value in 40960 = 8

                            Read_buff value in 46080 = 8

                            Read_buff value in 51200 = 8

                            Read_buff value in 56320 = 8

                            Read_buff value in 61440 = 8


                            As it is seen, writing data rate increased ~1.5 times relatively to 50 MHz clock and constituted 18.645 MBps.

                            Reading speed also increased about 1.5 times and reached 32.556 MBps.

                            The code in Modus 2.0 making this output is attached.

                            These data rates are not bad for many applications, but I need writing of at least 26 MBps!

                            This could be easily achieved by increasing block size 6x from 64K to 384K.

                            However, it seems to be difficult in Modus 2.0. Unfortunately, 64K limit stays in the description of the library:

                            PSoC 6 Peripheral Driver Library: SD Host (SD Host Controller)

                            Whether it is possible to rise this limit is not clear.

                            Any advises concerning how to do this are more than welcome.

                            May be, you can contact developers that wrote this library with this question?

                            One of possible approaches is to use ADMA3 that allows to transmit several blocks in one DMA request.

                            Thus, one can transmit 6 blocks of 64KB. However, it is not clear how fast this transfer could be.

                            Perhaps, single transfer of one 384KB block could be better.

                            Another option is to patch old Modus 1.1 code to remove secondary SD card initializations.

                            However, one also should look how to do this. Any advises are welcome.


                            With best regards,



                            1 of 1 people found this helpful
                            • 11. Re: CY8CPROTO-062-4343w SD card

                              Hi Rakshith,


                              it was also quite easy to increase SDHC buffer in Modus 2.0 from 64KB to 448KB.

                              One just had to change SDHC mode from default in syhal_sdhc.c ADMA2 to SDMA.

                              It seems to be that ADMA2 has 64KB limit, but SDMA has not. Thus, switching the

                              mode automatically allows to use larger buffer to boost data rate. To change this

                              setting one just  can override the library function where it is set cyhal_sdhc_init()

                              with another function that has required SDHC mode inside (SDMA). Perhaps, this is

                              not an universal solution because some function of the library may change their

                              behavior with SDMA. I did not test this. However, read/write works just perfect:


                              Starting write the 1st 448K block

                              Duration: 13523 us, Data rate: 33.924 MBps


                              Starting write the 2nd 448K block

                              Duration: 13523 us, Data rate: 33.924 MBps


                              Starting read the 1st 448K block

                              Duration: 10520 us, Data rate: 43.608 MBps


                              Starting read the 2nd 448K block

                              Duration: 10520 us, Data rate: 43.608 MBps


                              Interestingly, but cy_sd_host.c library in Modus 2.0 has only tiny improvements

                              comparatively to library in Modus 1.1. Necessity to reinitialize the card after each

                              operation in my code in Modus 1.1 was caused by some omissions.

                              In fact, SDHC works equally well in Modus 1.1 and 2.0, but Modus 2.0 adds

                              convenient high level library cyhal_sdhc that is lucking in 1.1.


                              Now the question about SDHC performance is closed completely.

                              Thank you very much for your help.


                              Happy programming!



                              1 of 1 people found this helpful
                              • 12. Re: CY8CPROTO-062-4343w SD card

                                Hello AlVy_2459421,


                                Thank you for the extensive testing. It is a great learning and will definitely help anyone who wants to use the SDHC driver.


                                As you have rightly observed some APIs are not available in the HAL SDHC Driver. There is an internal ticket created and our development team is working on creating HAL APIs to use all the features of SDHC block.


                                In one of your posts, you have mentioned -

                                However, physical powering of IO by 1.8V is not necessary. Just the driver should "know" that

                                low voltage signaling is allowed.

                                I did try giving the configuration to enable low voltage signaling and without any modifications, the SDHC initialization fails.

                                With low voltage signaling enabled -

                                With low voltage signaling disabled -

                                I have set 2 breakpoints, one for when the initialization fails and the other when the initialization succeeds. Can you please let me know if this is right and if this matches with your observations?


                                Thanks and Regards,

                                Rakshith M B

                                • 13. Re: CY8CPROTO-062-4343w SD card

                                  Hi Rakshith,


                                  thank  you for your comments.


                                  As you did not specify in which code did you make these changes, I supposed that you used your SDHC example.

                                  I placed these changes in this code and did not observed any improper behavior. I.e., my Samsung 128GB Evo Plus microSD card (white-red color) was properly initialized. I used the original CY8PROTO-062-4343W, i.e. without any hardware changes.

                                  Then I have tested the following microSD cards:


                                  Lexar 633x 32GB, black-blue: does NOT work

                                  Samsung 32GB, white-light blue: OK

                                  Samsung 4GB, white-light blue: OK

                                  Samsung Pro 8GB, black: does NOT work

                                  SanDisk Mobile Ultra 8GB, black: OK

                                  SanDisk Ultra 8GB, red-blue: does NOT work

                                  SanDisk Ultra 16GB, red-blue: does NOT work


                                  Thus, from 8 tested cards 4 did not work (50%).

                                  Then I retested cards that did not work in my modified CY8PROTO-062-4343W board with 1.8V signalling support, and 100MHz, and 448KB block in SDMA mode.

                                  Also, with the proper changes in software to support 3.3V/1.8V switching by the SDHC driver. Results:


                                  Lexar 633x 32GB, black-blue: OK

                                  Samsung Pro 8GB, black: does NOT work

                                  SanDisk Ultra 8GB, red-blue: does NOT work

                                  SanDisk Ultra 16GB, red-blue: does NOT work


                                  This is somewhat surprising because all these cards should support 1.8V signaling and high data rates:


                                  Samsung Pro 8GB should have reading up to 70 MBps, writing up to 20 MBps.

                                  SanDisk Ultra 8GB has speed up to 48 MBps or 320X.

                                  SanDisk Ultra 16GB has speed up to 98 MBps or 653X.


                                  May be, there are some small omissions like luck of delays that are needed.

                                  However, I don't have time for testing such things.


                                  Then I tested these remaining cards without low-voltage indication, i.e. with the original settings

                                  const cyhal_sdhc_config_t sdhc_config = {false, false, false, 4};

                                  in your code (with ADMA2 mode):


                                  Samsung Pro 8GB, black: OK

                                  SanDisk Ultra 8GB, red-blue: OK

                                  SanDisk Ultra 16GB, red-blue: OK


                                  Thus, the conclusion is that current low-voltage support is not universal, as it does not work with some (old and weak?) memory cards (Samsung Pro 8GB, black; SanDisk Ultra 8GB, red-blue; SanDisk Ultra 16GB, red-blue).

                                  The default original mode is OK for all cards.

                                  Also, some cards (Lexar 633x 32 GB black-blue) need real physical 1.8V signaling to work properly with the low-voltage setting.

                                  This is basically, in accordance with the SD specification.


                                  Concluding, one can use low-voltage signaling, and should use it for 100MHz mode, but some memory cards can have difficulties with it, even in spite of the fact that they formally should support low-voltage and high-frequency modes.


                                  Could you please indicate what type of microSD card did you use in the failed test?

                                  It seems to be that your card just fell into unlucky 50% cards that don't work in the tested configuration.


                                  Good luck!



                                  1 of 1 people found this helpful
                                  • 14. Re: CY8CPROTO-062-4343w SD card

                                    Problem with 100MHz clock in SDHC0 in Modus 2.0, omission in Help example around function Cy_SD_Host_Write()


                                    Hi Rakshith,


                                    I have tested SDHC0 because SDHC1 shares clock with Octal SPI. I can't rise clock at Octal SPI above 40-50 MHz for the reason of long wiring . Thus, I decided to switch to SDHC0 that has separate clock. The WiFi transmitter normally connected to SDHC0 in CY8CPROTO-062-4343W was disconnected from SDHC, and microSD socket was attached. However, this switching did not go as smoothly  as it should. I was able co configure SDHC0 for frequencies up to 50 MHz, but failed to make SDHC0 running at 100 MHz in Modus 2.0. The reason of this is unknown. Enabling of low voltage that helped before with SDHC1 did not help now with SDHC0. However, SDHC0 works perfectly at 100 MHz in Modus 1.1. Thus, the problem is in logic in Modus 2.0 code, and not in a bad electrical connection. I tried to look at the library code, but have found nothing.


                                    As the same time I completely fixed my code in Modus 1.1. It has happened that Cypress Help example had a very serious omission:

                                    command Cy_SD_Host_ClearNormalInterruptStatus(SDHC1, CY_SD_HOST_XFER_COMPLETE); that should terminate every write/read operation was omitted after the command Cy_SD_Host_Write. Please see screen shot attached. In fact, this command should stay after write command exactly in the same way how it stays after the read command:


                                    ret = Cy_SD_Host_Write(SDHC0, &data, &sdHostContext);  /* Write data to the card. */

                                            if (CY_SD_HOST_SUCCESS == ret)


                                                while (CY_SD_HOST_XFER_COMPLETE != (Cy_SD_Host_GetNormalInterruptStatus(SDHC0) & CY_SD_HOST_XFER_COMPLETE))


                                                    /* Wait for the data-transaction complete event. */


                                                /* Clear the data-transaction complete event. */

                                                Cy_SD_Host_ClearNormalInterruptStatus(SDHC0, CY_SD_HOST_XFER_COMPLETE);



                                    After fixing this issue mentioned earlier secondary SD card initializations became unnecessary.

                                    Now Modus 1.1 code is useful.


                                    Resuming, Modus 1.1 code works with SDHC0 and SDHC1 at 100 MHz,

                                    but Modus 2.0 code works in my hands with SDHC0 at 50 MHz and with SDHC1 at 100 MHz.

                                    For the time being I can use Modus 1.1, but in the future it would be nice to have Modus 2.0 because of its WiFi support. 


                                    All the best,



                                    1 2 Previous Next