8 Replies Latest reply on Jun 7, 2020 3:24 AM by MoTa_728816

    PSoC62 use SWD/USB lines as GPIO

    JeHu_3414236

      I am using the CY8C6247-D52 and I was wondering if I can change the function of P6.6/6.7 or USBDP/USBDM to regular GPIO at runtime.  It is configured normally for SWD and USB but in certain modes I want to use the pins as GPIO.

        • 1. Re: PSoC62 use SWD/USB lines as GPIO
          MoTa_728816

          Hi,

           

          I think that you can change the function of P6.6/P6.7 by configuring the HSIOM_PRT6_PORT_SEL0 / HSIOM_PRT6_PORT_SEL1 registers.

          For the details please refer to the Register TRM of PSoC 62. 14 High Speed IO Matrix (HSIOM) Registers.

          https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-62-register-technical-reference-manual…

           

          And also changing the drive mode of the pins will be required.

           

          moto

          • 2. Re: PSoC62 use SWD/USB lines as GPIO
            MoTa_728816

            Hi,

             

            Today, in a similar discussion,  I noticed the following description in the TRM.

            I think that you need to set IOMODE bit (bit 5) of USBDEV_USBIO_CR1 register.

             

            From PSoC 6 MCU: CY8C62x6, CY8C62x7 Architecture Technical Reference Manual (TRM)

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

            30.3.2.5 GPIO Mode Logic

            The D+ and D– pins can be used either as GPIO pins or

            USB I/O pins. This is controlled by the IOMODE bit of the

            USBDEV_USBIO_CR1 register. This bit should be set HIGH

            for GPIO functionality and LOW for USB operation.

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

             

            And in the PSoC 6 MCU: CY8C62x6, CY8C62x7 Registers Technical Reference Manual (TRM)

            USBFS0_USBDEV_USBIO_CR1 0x403F0048

            010-USBFS0_-_CR1.JPG

             

            So, how about trying

             

            *(uint32_t *)CYREG_USBFS0_USBDEV_USBIO_CR1 |= (0x01 << CYFLD_USBFS_USBDEV_IOMODE__OFFSET) ;

             

            moto

            • 3. Re: PSoC62 use SWD/USB lines as GPIO
              JeHu_3414236

              I am having some problems controlling the SWD pins as GPIO.  I do the initial setup to output like this and it works:

               

              const cy_stc_gpio_prt_config_t port6_cfg =

              {

              .out        = 0x00000008u,

              .intrMask   = 0x00000030u,

              .intrCfg    = 0x00000D00u,

              .cfg        = 0x00886666u,

              .cfgIn      = 0x00000000u,

              .cfgOut     = 0x00000000u,

              .cfgSIO     = 0x00000000u,

              .sel0Active = 0x00000000u,

              .sel1Active = 0x00000000u,

              };

              (void)Cy_GPIO_Port_Init(GPIO_PRT6, &port6_cfg);

              Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_6_GPIO); //swdio

              Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_7_GPIO); //swdclk

               

              I can set the pins to high/low.  When I try to reconfigure the pins to input then output, it stops working:

              Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_PULLUP, 1, P6_6_GPIO);

              Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_PULLUP, 1, P6_7_GPIO);

              //delay 100ms

              Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_6_GPIO); //swdio

              Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_7_GPIO); //swdclk

               

              The pins are always low even when I set to high.  Does anyone know what is the problem?

              • 4. Re: PSoC62 use SWD/USB lines as GPIO
                MoTa_728816

                Hi,

                 

                Your symptom seems that by changing the mode to input,

                the drive mode of the pin was changed to Open-drain driving low.

                (with this you can not drive the pin to high without pull-up resistor)

                 

                Please refer to the chapter GPIO_PRT6_CFG in the register TRM,

                (The manual says to reference GPIO_PRT2_CFG )

                 

                Or I would have a backup copy of port6_cfg and restore and re-initialize it with Cy_GPIO_Port_Init(),

                something like

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

                const cy_stc_gpio_prt_config_t port6_cfg =

                {

                .out        = 0x00000008u,

                .intrMask   = 0x00000030u,

                .intrCfg    = 0x00000D00u,

                .cfg        = 0x00886666u,

                .cfgIn      = 0x00000000u,

                .cfgOut     = 0x00000000u,

                .cfgSIO     = 0x00000000u,

                .sel0Active = 0x00000000u,

                .sel1Active = 0x00000000u,

                };

                 

                cy_stc_gpio_prt_config_t my_backup = port6_cfg ;

                 

                (void)Cy_GPIO_Port_Init(GPIO_PRT6, &port6_cfg);

                Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_6_GPIO); //swdio

                Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_7_GPIO); //swdclk

                 

                I can set the pins to high/low.  When I try to reconfigure the pins to input then output, it stops working:

                Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_PULLUP, 1, P6_6_GPIO);

                Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_PULLUP, 1, P6_7_GPIO);

                 

                //delay 100ms

                (void)Cy_GPIO_Port_Init(GPIO_PRT6, &my_backup);

                // or just call (void)Cy_GPIO_Port_Init(GPIO_PRT6, &port6_cfg); again...

                Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_6_GPIO); //swdio

                Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_7_GPIO); //swdclk

                 

                moto

                P.S. I'm sorry, but I have not test this by myself, so this is just my idea.

                • 5. Re: PSoC62 use SWD/USB lines as GPIO
                  JeHu_3414236

                  Thanks.  Is there some problem with calling Cy_GPIO_Pin_FastInit() to initialize the gpio?  It fails even if I keep setting to output but just changing the output value. It looks like only the first time I call it, then it works.

                   

                  Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_6_GPIO); //swdio

                  Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_STRONG_IN_OFF, 0, P6_7_GPIO); //swdclk

                  //delay 100ms

                  Cy_GPIO_Pin_FastInit(GPIO_PRT6, 6, CY_GPIO_DM_STRONG_IN_OFF, 1, P6_6_GPIO); //swdio

                  Cy_GPIO_Pin_FastInit(GPIO_PRT6, 7, CY_GPIO_DM_STRONG_IN_OFF, 1, P6_7_GPIO); //swdclk

                  • 6. Re: PSoC62 use SWD/USB lines as GPIO
                    MoTa_728816

                    Hi,

                     

                    > Thanks.  Is there some problem with calling Cy_GPIO_Pin_FastInit() to initialize the gpio? 

                    > It fails even if I keep setting to output but just changing the output value.

                    > It looks like only the first time I call it, then it works.

                     

                    I'm sorry for my thoughtless response.

                     

                     

                    From what you saw, Cy_GPIO_Pin_FastInit() must have some initialization function along with the setting the mode.

                     

                    Note: I'm checking with PSoC Creator.

                     

                    In that cy_gpio.h / cy_gpio.c

                    There are functions like

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

                    __STATIC_INLINE void Cy_GPIO_SetDrivemode(GPIO_PRT_Type* base, uint32_t pinNum, uint32_t value);

                    __STATIC_INLINE uint32_t Cy_GPIO_GetDrivemode(GPIO_PRT_Type* base, uint32_t pinNum);

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

                     

                    So may be, getting the Driver mode using Cy_GPIO_GetDrivemode() before changing the pin state

                    and restoring it with Cy_GPIO_SetDrivemode() will work.

                     

                    moto

                     

                     

                     

                    • 7. Re: PSoC62 use SWD/USB lines as GPIO
                      JeHu_3414236

                      Thank you.  I am trying to use the SWD lines as a I2C master using software bit-bang.  There is only 1 slave and 1 master connected.  I keep clock as output and only switch data line between output and input.  I would like to avoid using external pull-up resistor on the data line.  I attached the code I used and the output looks correct on a scope but when I connect to a I2C slave, I always get NACK after writing.  Can you see any problems with the code?

                      • 8. Re: PSoC62 use SWD/USB lines as GPIO
                        MoTa_728816

                        Hi,

                         

                        Although I have not been able to read your code fully.

                        ACK/NACK wil be returned  (or read) at the 9th clock rising edge.

                         

                        So before you return the SCL to high after sending the 8th bit,

                        (I think) you need to change the direction of the pin

                        and with the next clock rising edge the value for ack/nack must be read.

                         

                        So I would try (pseudo code and have not tried by myself, sorry)

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

                        uint8_t I2C__P_GetACK(void)

                        {

                             /* set SDA pin mode input register pulled-up */

                            /* may be we need some delay to let the slave prepare the answer */

                            /* SCL = 1 */

                           /* read value for ack/nack */

                           /* SCL = 0 */

                           /* return SDA pin mode to the previous value */

                           return( result ) ;

                        }

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

                         

                        moto