Concurrent GPIO/CDC operation for the CY7C65213

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

cross mob
emagii
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

Hi, I am thinking about an application to control an embedded linux computer using the CY7C65213.

I would need the following functions to work concurrently.

1. USB-UART Bridge (TX+RX)

2. 4 port GPIO output only to control the boot mode

3. Reset Port using GPIO

Does the Windows driver allow both UART and GPIO to work at the same time?

The linux driver only support UART, and not GPIO.

I believe in linux, this means that concurrent UART + GPIO is not possible, because if the linux driver for the serial port is loaded, you cannot open the chip using libusb.

If I write a linux driver supporting both, is it possible to get a product id using the Cypress Vendor Id?

I am using the SparkFun CY7C65213 board for testing right now.

https://www.sparkfun.com/products/13830

so allocating a product id for that would be sufficient.

Is it possible to get information allowing the driver to program the internal EEPROM?

 

I guess that info on how to read/write the EEPROM and a description of the fields would be a good start.

0 Likes
1 Solution
narolkarvarun
Moderator
Moderator
Moderator
5 likes given 100 solutions authored 250 replies posted

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <signal.h>

#include <stdbool.h>
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#include <ctype.h>

#include "../../common/header/CyUSBSerial.h"

unsigned int getNumberOfDevices(void) 
{     
    unsigned int num = 255;       
    CyGetListofDevices(&num);      
    return num;
} /* This function is used to find Cypress device */
        
bool isCypressDevice(int deviceNum) 
{
    CY_HANDLE handle;     
    unsigned char signature[6];     
    CY_RETURN_STATUS rStatus;     
    rStatus = CyOpen (deviceNum, 2, &handle);    
    printf("%u\n",rStatus); 
    if (rStatus != CY_SUCCESS)     
    {         
        return false;     
    }      
    rStatus = CyGetSignature (handle, signature);     
    if (rStatus == CY_SUCCESS)     
    {         
        CyClose (handle);         
        return 1;     
    }     
    else    
    {         
        return 0;     
    } 
}

int findCypressDevice() 
{     
    unsigned int num_devices = getNumberOfDevices();     
    for (unsigned int curdev = 0; curdev < num_devices; curdev++)     
    {          
        if (isCypressDevice(curdev))       //curdev  6             
        return 6;     
    }     
    return -1; 
} 

int main() 
{     
    CY_HANDLE handle;     
    unsigned int device;     
    CY_RETURN_STATUS rStatus;     
    CY_DEVICE_INFO deviceInfo;     
    UINT8 value = 0;
    rStatus = CyLibraryInit (); //Initates Cypress Library    
    if (rStatus != CY_SUCCESS)     
    {         
        printf ("CY:Error in Doing library init Error NO:<%d> \n", rStatus);         
        return rStatus;     
    }
    device = findCypressDevice(); //This function is used to detect Cypress device connected to USB bus.    
    printf("device : %d\n",device); 
    if (device < 0)     
    {         
        return 0;     
    }     
    rStatus = CyGetDeviceInfo(device, &deviceInfo); //This API is used to get information(VID,PID) about detected Cypress device.      
    printf("deviceInfo :%d\n",rStatus); 
    if (rStatus != CY_SUCCESS)     
    {         
        return 0;     
    }     
    rStatus = CyOpen(device, 2, &handle); //This API is used to open Cypress device (Gets handle of device)    
    printf("deviceOpen %d\n",rStatus); 
    if (rStatus != CY_SUCCESS)     
    {         
        return 0;     
    }

    while (1)
    {
        rStatus=CySetGpioValue(handle,10,value); //This API is used to set value of GPIO1 to 0.      
        printf("%d\n",rStatus); 
        value = ~value;
        if (rStatus == CY_SUCCESS)     
        {
            printf("Value changed \n");     
        }     
        else    
        {         
            printf("Not changed \n");     
        }       

        sleep(1);
    }    

    rStatus=CyGetGpioValue(handle,10,&value); //This API is used to retrieve value of GPIO1.      
    if (rStatus == CY_SUCCESS)     
    {         
        printf("Value retrieved %d\n",value);     
    }     
    else    
    {         
        printf("Not changed\n");     
    }     
    
    rStatus= CyClose(handle); //This API is used to close the Cypress device.    
    if (rStatus == CY_SUCCESS)     
    {     
        printf("Device closed\n");     
    }     
    else    
    {         
        printf("Not closed\n");     
    }     
    CyLibraryExit (); //This API is used to exit library.
}     /* This function is used to get number of connected Cypress Devices */

 

Hi emagii ,

please check the attached file where we have written the example where you can access GPIO while working on the CDC class.

you can change GPIO Number at line number 91 .(ex.  GPIO 10).

Thank you 

Varun Narolkar

 

 

 

View solution in original post

0 Likes
11 Replies
narolkarvarun
Moderator
Moderator
Moderator
5 likes given 100 solutions authored 250 replies posted

Hi Emagii,

Yes you can configure UART and GPIO from USB serial configuration utility tool.

The GPIOs can be configured as input/output/tristate from the USB-Serial Configuration Utility. Once the GPIO's functionality is configured, the GPIO current value is set/get depending on the configuration(input/output) using the CyUSBSerial Library through a host application. There is no separate driver needed for that. You can refer the USB-Serial API doc to control the GPIO operation from USB-Serial SDK.

Please note that the APIs CyReadUserFlash and CyProgUserFlash are used to read and write into the User Flash area which is 512 Bytes. This has nothing to do with the configuration file. i.e In the UserFlash area you can store any information and read it but cannot modify the particular memory area used by the configuration utility. Please refer to the API guide for more details on the API and the area of the flash that it can program "CyProgUserFlash".

 

Thank you 

Varun Narolkar

 

 

0 Likes

Sorry, but since we are running on a mixed Linux/Windows environment, I am looking for a way to emulate the functionality of the USB-Serial configuration utility on linux.

It is not so that ”I dont need a driver” 

I want to have a GPIO driver, because it simplifies a lot of things.

On Windows, I want a standard Windows COM port, and the capability to toggle the GPIO pins while the COM port is active.

Any code I write should not have to touch the serial part.

I do not feel that this is clear from you answer.

0 Likes
narolkarvarun
Moderator
Moderator
Moderator
5 likes given 100 solutions authored 250 replies posted

Hi Emagii ,

 I am Sorry for Late Comment .

"May I know For which product class (CDC/Vendor) you need VID & PID? "

"For GPIO Functionality check below information "

The USB Serial bridge controller supports I/O control using APIs in Windows, Linux, Android and Mac-OS systems. The status of the input GPIO can be retrieved by using the CyGetGPIOValue() API and the status of GPIO can be set to Drive 1 or Drive 0 by using the CySetGPIOValue() API.

The above-mentioned APIs can only be used when the device in configured for Vendor mode.  When configured in CDC mode, the APIs cannot be used as they require the device to be bound to vendor driver.

For configuring the gpios in CDC mode, we need to modify the CDC_ACM driver code and add the code to drive gpios from it.

For more information please follow below given KBA Link.

https://community.infineon.com/t5/Knowledge-Base-Articles/USB-Serial-Bridge-Controller-Managing-I-Os...

https://community.infineon.com/t5/USB-low-full-high-speed/CY65215A-USB-GPIO-support-for-Linux/m-p/33...

 

Regards

Varun Narolkar

 

0 Likes

My goal is to have a linux driver which supports running the CY7C65213
as a CDC device, but the driver would also export the GPIO functionality
so they appear in /sys/class/gpio on a linux system.

I think I can write this driver myself, based on the existing driver in linux
located at linux:/drivers/usb/serial/cypress_m8.c

When registering the UART, it also needs to register the GPIO in the same driver.

I do not have a registered USB Vendor Id - it costs a lot of money.
So my suggestion is that you allocate a product id for a Combo CDC + GPIO product.

Then I can start developing an enhanced linux driver based on this.

There is a list of USB vendors at  http://www.linux-usb.org/usb.ids

Cypress have the vendor id: 04b4 and the following product ids.

04b4  Cypress Semiconductor Corp.
	0001  Mouse
	0002  CY7C63x0x Thermometer
	0008  CDC ACM serial port
	0033  Mouse
	0060  Wireless optical mouse
	00f3  FX3 micro-controller (DFU mode)
	0100  Cino FuzzyScan F760-B
	0101  Keyboard/Hub
	0102  Keyboard with APM
	0130  MyIRC Remote Receiver
	0306  Telephone Receiver
	0407  Optical Skype Mouse
	0818  AE-SMKD92-* [Thumb Keyboard]
	0bad  MetaGeek Wi-Spy
	1002  CY7C63001 R100 FM Radio
	1006  Human Interface Device
	2050  hub
	2830  Opera1 DVB-S (cold state)
	3813  NANO BIOS Programmer
	4235  Monitor 02 Driver
	4381  SCAPS USC-1 Scanner Controller
	4611  Storage Adapter FX2 (CY)
	4616  Flash Disk (TPP)
	4624  DS-Xtreme Flash Card
	4717  West Bridge
	5201  Combi Keyboard-Hub (Hub)
	5202  Combi Keyboard-Hub (Keyboard)
	5500  HID->COM RS232 Adapter
	5a9b  Dacal CD/DVD Library D-101/DC-300/DC-016RW
	6022  Hantek DSO-6022BE
	602a  Hantek DSO-6022BL
	6370  ViewMate Desktop Mouse CC2201
	6502  CY4609
	6506  CY4603
	650a  CY4613
	6560  CY7C65640 USB-2.0 "TetraHub"
	6570  Unprogrammed CY7C65632/34 hub HX2VL
	6572  Unprogrammed CY7C65642 hub
	6830  CY7C68300A EZ-USB AT2 USB 2.0 to ATA/ATAPI
	6831  Storage Adapter ISD-300LP (CY)
	7417  Wireless PC Lock/Ultra Mouse
	8329  USB To keyboard/Mouse Converter
	8613  CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
	8614  DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
	861f  Anysee E30 USB 2.0 DVB-T Receiver
	bca1  Barcode Reader
	cc04  Centor USB RACIA-ALVAR USB PORT
	cc06  Centor-P RACIA-ALVAR USB PORT
	d5d5  CY7C63x0x Zoltrix Z-Boxer GamePad
	de61  Barcode Reader
	de64  Barcode Reader
	f000  CY30700 Licorice evaluation board
	f111  CY8CKIT-002 PSoC MiniProg3 Rev A Program and debug kit
	f115  PSoC FirstTouch Programmer
	f139  KitProg
	f231  DELLY Changer 4in1 universal IR remote
	f232  Mono embedded computer
	fd10  Gembird MSIS-PM
	fd13  Energenie EG-PMS
	fd15  Energenie EG-PMS2

This is 60 devices, and Cypress is allowed to have 2^16 or 65536 so it is not a scarce resource.

You already have some "combo" devices.
5201 Combi Keyboard-Hub (Hub)
5202 Combi Keyboard-Hub (Keyboard)

My suggestion is that you add:

5213 Combi CDC + GPIO

The vendor/productid would for the Combo part would be 04b4:5213

I think it would be a really good idea for you to develop such a driver for Windows.


Right now, I see your competition is FTDI.
I have used the FT4232 which is treated driverwise as a USB hub with 4 block, each handling 8 pins.
You can configure each block as a CDC device, and they will appear as  COM device in Windows and a /dev/ttyUSBx in Linux. Two ports can be configured as a Multiprotocol device and be used as GPIO.
There are a lot of things in the FT device we did not like when we ran it in the project,
and the CY7C65213 is superior in many ways, with total footprint of the solution
being the most important. But not beeing able to run CDC and GPIO at the same time is a show stopper.
I think I can fix that in Linux.

So, can we allocate 04B4:5213 for a "Combi CDC + GPIO" or a "Combo CY7C65213 driver"?
You would need to add this to your internal lists and maybe inform the guys at www.linux-usb.org.

0 Likes
narolkarvarun
Moderator
Moderator
Moderator
5 likes given 100 solutions authored 250 replies posted

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <signal.h>

#include <stdbool.h>
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#include <ctype.h>

#include "../../common/header/CyUSBSerial.h"

unsigned int getNumberOfDevices(void) 
{     
    unsigned int num = 255;       
    CyGetListofDevices(&num);      
    return num;
} /* This function is used to find Cypress device */
        
bool isCypressDevice(int deviceNum) 
{
    CY_HANDLE handle;     
    unsigned char signature[6];     
    CY_RETURN_STATUS rStatus;     
    rStatus = CyOpen (deviceNum, 2, &handle);    
    printf("%u\n",rStatus); 
    if (rStatus != CY_SUCCESS)     
    {         
        return false;     
    }      
    rStatus = CyGetSignature (handle, signature);     
    if (rStatus == CY_SUCCESS)     
    {         
        CyClose (handle);         
        return 1;     
    }     
    else    
    {         
        return 0;     
    } 
}

int findCypressDevice() 
{     
    unsigned int num_devices = getNumberOfDevices();     
    for (unsigned int curdev = 0; curdev < num_devices; curdev++)     
    {          
        if (isCypressDevice(curdev))       //curdev  6             
        return 6;     
    }     
    return -1; 
} 

int main() 
{     
    CY_HANDLE handle;     
    unsigned int device;     
    CY_RETURN_STATUS rStatus;     
    CY_DEVICE_INFO deviceInfo;     
    UINT8 value = 0;
    rStatus = CyLibraryInit (); //Initates Cypress Library    
    if (rStatus != CY_SUCCESS)     
    {         
        printf ("CY:Error in Doing library init Error NO:<%d> \n", rStatus);         
        return rStatus;     
    }
    device = findCypressDevice(); //This function is used to detect Cypress device connected to USB bus.    
    printf("device : %d\n",device); 
    if (device < 0)     
    {         
        return 0;     
    }     
    rStatus = CyGetDeviceInfo(device, &deviceInfo); //This API is used to get information(VID,PID) about detected Cypress device.      
    printf("deviceInfo :%d\n",rStatus); 
    if (rStatus != CY_SUCCESS)     
    {         
        return 0;     
    }     
    rStatus = CyOpen(device, 2, &handle); //This API is used to open Cypress device (Gets handle of device)    
    printf("deviceOpen %d\n",rStatus); 
    if (rStatus != CY_SUCCESS)     
    {         
        return 0;     
    }

    while (1)
    {
        rStatus=CySetGpioValue(handle,10,value); //This API is used to set value of GPIO1 to 0.      
        printf("%d\n",rStatus); 
        value = ~value;
        if (rStatus == CY_SUCCESS)     
        {
            printf("Value changed \n");     
        }     
        else    
        {         
            printf("Not changed \n");     
        }       

        sleep(1);
    }    

    rStatus=CyGetGpioValue(handle,10,&value); //This API is used to retrieve value of GPIO1.      
    if (rStatus == CY_SUCCESS)     
    {         
        printf("Value retrieved %d\n",value);     
    }     
    else    
    {         
        printf("Not changed\n");     
    }     
    
    rStatus= CyClose(handle); //This API is used to close the Cypress device.    
    if (rStatus == CY_SUCCESS)     
    {     
        printf("Device closed\n");     
    }     
    else    
    {         
        printf("Not closed\n");     
    }     
    CyLibraryExit (); //This API is used to exit library.
}     /* This function is used to get number of connected Cypress Devices */

 

Hi emagii ,

please check the attached file where we have written the example where you can access GPIO while working on the CDC class.

you can change GPIO Number at line number 91 .(ex.  GPIO 10).

Thank you 

Varun Narolkar

 

 

 

0 Likes

We need to be able to toggle a GPIO pin between TRISTATE and DRIVE0 to simulate an open-collector output.
There is an external pull-up on this signal.

The linux library: CyUSBCommon.h contains the CY_GPIO_SET_CONFIG_CMD command, which i suspect is useful. I did not find it beeing documented anywhere.
Is there any documentation on how to use this?

 

0 Likes
emagii
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

Thank You.
The line.

rStatus=CySetGpioValue(handle,10,value); //This API is used to set value of GPIO1 to 0.

Should that not be changed to

rStatus=CySetGpioValue(handle,1,value); //This API is used to set value of GPIO1 to 0.

to work on GPIO 1?

0 Likes
narolkarvarun
Moderator
Moderator
Moderator
5 likes given 100 solutions authored 250 replies posted

Hi Emaggi,

yes, you can use any available GPIO.

Thank you 

Varun Narolkar

 

0 Likes
narolkarvarun
Moderator
Moderator
Moderator
5 likes given 100 solutions authored 250 replies posted

Hi Emaggi,

if GPIO1 is not configured from the USB Configuration utility Tool, you can use it.

Make sure it is not being used for any other purpose before using it.

Thank You 

Varun Narolkar

0 Likes

The change between input and output needs to be done in a running system.

It is used to generate a reset to another CPU.

You normally have the GPIO configured as an input and a pullup drives the signal high.

Your chip is one of several sources that can pull the signal low.

You do this by first configuring the GPIO to drive the signal low (while still an input).

Then you reconfigure the signal to be an output - which will pull the signal low.

You configure some other outputs to define a bootmode for the other CPU.

(It samples those pins at reset)

Then you change the GPIO to be an input, and the pullup will pull the signal high.

You do not want to start the USB Configuration tool for this.

 

0 Likes
narolkarvarun
Moderator
Moderator
Moderator
5 likes given 100 solutions authored 250 replies posted

Hi emagii ,

I'm sorry, but CY7C65213 does not support runtime dynamic configuration updates.

Thank you

Varun Narolkar

0 Likes