PSoC62 use SWD/USB lines as GPIO

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

cross mob
JeHu_3414236
Level 5
Level 5
10 likes received First like received

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.

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

View solution in original post

0 Likes
8 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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-techni...

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

moto

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes

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?

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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.

0 Likes

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

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes
lock attach
Attachments are accessible only for community members.

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?

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes