3 Replies Latest reply on Sep 27, 2019 3:07 AM by DheerajK_81

    Switching between GPIO and SMIF on SMIF pins


      I have a modified PSoC 6 Pioneer Kit that uses a different NOR-flash device from the one provided by the Kit; I have been able to run simple SPI commands on it, but now need to try something completely different. Between doing SMIF-related operations (e.g., programming/erasing memory, reading status), I need to occasionally do some GPIO operations involving some of the same pins, i.e., SMIF_SS0_PIN, SMIF_DATA_PIN, SMIF_SPI_CLOCK_PIN.  In effect, I want to try:

      1. write enable (06h) - sets Write Enable Latch
      2. read status (05h)
      3. do a GPIO op - clears Write Enable Latch as a side-effect
      4. read status (05h)


      It has been pointed out to me that on some MCUs, SPI and GPIO functions on the same pins go through a function multiplexor, and the desired function needs to be assigned in advance. Is there such a function multiplexer on PSoC 6 for the SMIF pins? Is there example code for how to do this?  For example, could I toggle out a soft reset command (e.g., F0h on S25FL512S) over GPIO before returning to SMIF to read the status?

        • 1. Re: Switching between GPIO and SMIF on SMIF pins

          Yes, you can definitely do it. From the I/O Cell Architecture section in the PSoC63 Architecture TRM you can find out what pins are routed to the multiplexer and have multilple functionalities as shown below:



          The line ACTIVE[15:3] corresponds to the ACT columns (Page#28) in the datasheet and the SMIF lines we are interested in are part of ACT#6 as highlighted below:



          Now to change the functionalities, please refer to the following KBAs which will give you insight on how this can be done:


          Refer the HSIOM_PRT11_PORT_SEL0 register (Page#642) in the Register TRM and alternate between "0x0: GPIO" and "0x12: ACT_6" values.




          • 2. Re: Switching between GPIO and SMIF on SMIF pins

            Thank you.  That helps, but I’m having trouble mapping this to actual code.  I am using ModusToolbox 1.1.  In looking at the description in “Controlling SPI I/O Pins Through Firmware for PSoC 6 MCU Devices - KBA226844”, it doesn’t quite match the environment I have.


            The KBA mentions using TopDesign - I see references to this in the context of PSoC Creator, but not ModusToolbox.


            I see HSIOM_PRT11_PORT_SEL0 in the Register TRM.  But I don’t see a #define for this within the PSoC 6 SDK. (I am looking under “ModusToolbox_1.1/libraries”.) The closest #defines I can find to this are in “cy8c6347bzi_bld53.h” in directory “components/psoc6pdl/devices/psoc6/include”.  In particular,


            #define HSIOM_PRT11             ((HSIOM_PRT_Type*) &HSIOM->PRT[11])               /* 0x403100B0 */


            Looking elsewhere in the SDK, it seems that there are related HSIOM definitions in “cyip_hsiom.h” and “cyip_hsiom_v2.h” located in “components/psoc6pdl/devices/psoc6/include/ip”. But it’s not clear how to bring these pieces together, or am I in a piece of API that I shouldn’t touch…


            So… within the ModusToolbox SDK for PSoC 6, are there certain header files and driver functions that I should pay attention to?

            • 3. Re: Switching between GPIO and SMIF on SMIF pins

              Sorry, I assumed you are using PSoC Creator. It is even easier if you use ModusToolbox. To change the functionality of the HSIOM, there is "Cy_GPIO_SetHSIOM()" and "Cy_GPIO_GetHSIOM" API.


              Let's say you have named the SMIF pins SS and Data pin as "SMIF_SS0" and "SMIF_DATA0" respectively in the device configurator and you want to change them to GPIOs for certain part of the code. Here is a snippet of how you would do so:


              /* Set HSIOM Mode of the required pins to GPIO */
                  /* Set the required drive mode for the GPIO pins */
                  Cy_GPIO_SetDrivemode(SMIF_SS0_PORT, SMIF_SS0_NUM, CY_GPIO_DM_STRONG_IN_OFF);
                  Cy_GPIO_SetDrivemode(SMIF_DATA0_PORT, SMIF_DATA0_NUM, CY_GPIO_DM_STRONG_IN_OFF);
                  /* Check if the HSIOM has changed or not */
                  printf("\r\n GPIO Mode: %d\r\n", Cy_GPIO_GetHSIOM(SMIF_SS0_PORT, SMIF_SS0_NUM));
                  /* Perform any operation on the GPIO pins */
                  for(int i = 0; i < 2; i++){
                  Cy_GPIO_Inv(SMIF_SS0_PORT, SMIF_SS0_NUM);
                  Cy_GPIO_Inv(SMIF_DATA0_PORT, SMIF_DATA0_NUM);
                  /* Change GPIO back to SMIF functionality (ACT#5) */
                  /* Set the correct drive modes */
                  Cy_GPIO_SetDrivemode(SMIF_DATA0_PORT, SMIF_DATA0_NUM, CY_GPIO_DM_STRONG);


              As you can see, we first change the HSIOM mode. All the HSIOM modes are defined in an enum present in the "gpio_psoc6_01_116_bga_ble.h" which can be found in the following directory:


              Secondly, you need to set the drive modes after changing the HSIOM before usage.


              Once, you have completed your operation, you can switch back using the same principle.


              Signal scopeshots when the above code works: