Files
tinio/release/cylib/tools/cyusbserialtest.c
[ Kristjan Komloši HomePC ] def99f209a 5more mins
2017-03-09 16:51:38 +01:00

604 lines
21 KiB
C

/*
* Test utility
* Copyright (C) 2013 Cypress Semiconductor
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#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 "CyUSBSerial.h"
#define CY_MAX_DEVICES 30
#define CY_MAX_INTERFACES 4
typedef struct _CY_DEVICE_STRUCT {
int deviceNumber;
int interfaceFunctionality[CY_MAX_INTERFACES];
bool isI2c;
bool isSpi;
int numInterface;
}CY_DEVICE_STRUCT;
CY_DEVICE_STRUCT *glDevice;
int i2cDeviceIndex[CY_MAX_DEVICES][CY_MAX_INTERFACES];
unsigned char *deviceNumber = NULL;
int cyDevices, i2cDevices = 0;
UINT8 numDevices = 0;
int selectedDeviceNum = -1, selectedInterfaceNum = -1;
bool exitApp = false;
short pageAddress = -1;
short readWriteLength = -1;
bool deviceAddedRemoved = false;
int i2cVerifyData (int deviceNumber, int interfaceNum);
void printListOfDevices (bool isPrint);
int spiVerifyData (int deviceNumber, int interfaceNum);
int getUserInput()
{
char userInput[6], x;
int output,i = 0;
bool isDigit = true;
x = getchar();
while (x != '\n'){
if (i < 5){
userInput[i] = x;
i++;
}
if (!isdigit(x))
isDigit = false;
x = getchar();
}
userInput[i] = '\0';
if (isDigit == false)
return -1;
output = atoi(userInput);
return output;
}
void deviceHotPlug () {
CY_RETURN_STATUS rStatus;
deviceAddedRemoved = true;
selectedDeviceNum = -1;
selectedInterfaceNum = -1;
printf ("Device of interest Removed/Added \n");
rStatus = CyGetListofDevices (&numDevices);
if (rStatus != CY_SUCCESS) {
printf ("CY:Error in Getting List of Devices: Error NO:<%d> \n", rStatus);
}
printListOfDevices (false);
}
int main (int argc, char **agrv)
{
int userInput;
int tempSelectedDeviceNum, tempSelectedInterfaceNum, tempPageAddress, tempLength;
CY_RETURN_STATUS rStatus;
signal (SIGUSR1, deviceHotPlug);
glDevice = (CY_DEVICE_STRUCT *)malloc (CY_MAX_DEVICES *sizeof (CY_DEVICE_STRUCT));
if (glDevice == NULL){
printf ("Memory allocation failed ...!! \n");
return -1;
}
rStatus = CyLibraryInit ();
if (rStatus != CY_SUCCESS) {
printf ("CY:Error in Doing library init Error NO:<%d> \n", rStatus);
return rStatus;
}
rStatus = CyGetListofDevices (&numDevices);
if (rStatus != CY_SUCCESS) {
printf ("CY:Error in Getting List of Devices: Error NO:<%d> \n", rStatus);
return rStatus;
}
printListOfDevices(true);
do {
printf ("-------------------------------------------------------------------\n");
printf ("1: Print list of devices \n");
if (selectedDeviceNum != -1 && selectedInterfaceNum != -1){
printf ("2: Change device selection--selected device: [Device number %d] : [Interface No %d]",\
selectedDeviceNum, selectedInterfaceNum);
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_I2C)
printf (" : I2C\n");
else if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_SPI)
printf (" : SPI\n");
else
printf (" : NA\n");
}
else
printf ("2: Select device...No device selected !!\n");
if (readWriteLength != -1 && pageAddress != -1){
printf ("3: Change Flash page address and length ...Entered is page address %d and length %d\n", pageAddress, readWriteLength);
printf ("4: Verify data\n5: Exit\n");
}
else
printf ("3: Enter I2C/SPI Flash page address and length to write/read.\n4: Verify data\n5: Exit\n");
printf ("-------------------------------------------------------------------\n");
userInput = getUserInput();
if (userInput < 1 || userInput > 5){
printf ("Wrong selection code ... Enter again \n");
continue;
}
switch (userInput){
case 1:
printListOfDevices(true);
break;
case 2:
if (cyDevices == 0) {
printf ("No device of interest connected ...!!\n");
continue;
}
printf ("Enter Device number to be selected.. \n");
tempSelectedDeviceNum = getUserInput();
//printf ("Selected device number is %d \n",tempSelectedDeviceNum);
if (tempSelectedDeviceNum >= cyDevices || tempSelectedDeviceNum == -1){
printf ("Wrong device selection \n");
continue;
}
printf ("Enter interface number..\n");
tempSelectedInterfaceNum = getUserInput();
//printf ("Selected device number is %d %d\n",tempSelectedInterfaceNum, glDevice[tempSelectedDeviceNum].numInterface);
if (tempSelectedInterfaceNum >= glDevice[tempSelectedDeviceNum].numInterface ||
tempSelectedInterfaceNum == -1) {
printf ("Wrong interface Selection selection \n");
continue;
}
if (glDevice[tempSelectedDeviceNum].interfaceFunctionality[tempSelectedInterfaceNum] == -1){
printf ("Selected device does not have I2C or SPI !!! \n");
continue;
}
if (deviceAddedRemoved == true) {
printf ("Device of interest was added/removed .... Print and select from new list\n");
continue;
}
selectedDeviceNum = tempSelectedDeviceNum;
selectedInterfaceNum = tempSelectedInterfaceNum;
//pageAddress = -1;
//readWriteLength = -1;
break;
case 3:
if (selectedDeviceNum == -1) {
printf ("Select proper device!!! \n");
continue;
}
if (selectedDeviceNum >= cyDevices){
printf ("Select proper device!!! \n");
continue;
}
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_I2C){
printf ("Enter Page address... (less than 256)\n");
tempPageAddress = getUserInput();
printf ("Enter length to read/write...(less than 64)\n");
tempLength = getUserInput();
if (deviceAddedRemoved == true) {
printf ("Device of interest was added/removed .... Print and select from new list\n");
continue;
}
if (tempPageAddress > 256){
printf ("Invalid page address ..Enter page address less than 256 (1 bytes len)\n");
continue;
}
if (tempLength < 0 || tempLength > 64){
printf ("Invalid Length ..Enter length less than 64 bytes\n");
continue;
}
pageAddress = tempPageAddress;
readWriteLength = tempLength;
break;
}
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_SPI){
printf ("Enter Page address... (less than 65536)\n");
tempPageAddress = getUserInput();
printf ("Enter length to read/write...(less than 256)\n");
tempLength = getUserInput();
if (deviceAddedRemoved == true) {
printf ("Device of interest was added/removed .... Print and select from new list\n");
continue;
}
if (tempPageAddress > 65536){
printf ("Invalid page address ..Enter page address less than 65536 (1 bytes len)\n");
continue;
}
if (tempLength < 0 || tempLength > 256){
printf ("Invalid Length ..Enter length less than 256 bytes\n");
continue;
}
pageAddress = tempPageAddress;
readWriteLength = tempLength;
break;
}
case 4:
if (selectedDeviceNum == -1) {
printf ("Select proper device!!! \n");
continue;
}
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == -1){
printf ("Selected device does not have I2C or SPI !!! \n");
continue;
}
if ((pageAddress == -1) || (readWriteLength == -1)){
printf ("Select proper page address and length !!! \n");
continue;
}
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_I2C){
if (pageAddress > 256){
printf ("Invalid Page address for I2C .. need to be less than 256\n");
continue;
}
if (readWriteLength > 64){
printf ("Invalid read write length for I2C .. need to be less than 64\n");
continue;
}
printf ("Calling I2C \n");
i2cVerifyData(glDevice[selectedDeviceNum].deviceNumber, selectedInterfaceNum);
}
if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_SPI){
spiVerifyData(glDevice[selectedDeviceNum].deviceNumber, selectedInterfaceNum);
}
break;
case 5:
exitApp = true;
CyLibraryExit ();
break;
}
}while (exitApp == false);
free (glDevice);
return CY_SUCCESS;
}
int spiWriteEnable (CY_HANDLE handle)
{
unsigned char wr_data,rd_data;
CY_RETURN_STATUS status = CY_SUCCESS;
CY_DATA_BUFFER writeBuf;
CY_DATA_BUFFER readBuf;
writeBuf.buffer = &wr_data;
writeBuf.length = 1;
readBuf.buffer = &rd_data;
readBuf.length = 1;
wr_data = 0x06; /* Write enable */
status = CySpiReadWrite (handle, &readBuf, &writeBuf, 5000);
return status;
}
//Helper functions for doing data transfer to/from SPI flash
int spiWaitForIdle (CY_HANDLE handle)
{
char rd_data[2], wr_data[2];
CY_DATA_BUFFER writeBuf, readBuf;
writeBuf.length = 2;
writeBuf.buffer = (unsigned char *)wr_data;
int timeout = 0xFFFF;
CY_RETURN_STATUS status;
readBuf.length = 2;
readBuf.buffer = (unsigned char *)rd_data;
do
{
wr_data[0] = 0x05; /* Status */
status = CySpiReadWrite (handle, &readBuf, &writeBuf, 5000);
if (status != CY_SUCCESS)
{
break;
}
timeout--;
if (timeout == 0)
{
status = CY_ERROR_IO_TIMEOUT;
return status;
}
} while (rd_data[1] & 0x01);
return status;
}
int spiVerifyData (int deviceNumber, int interfaceNum)
{
CY_DATA_BUFFER dataBufferWrite,dataBufferRead;
CY_HANDLE handle;
bool isVerify = true;
unsigned char wbuffer[256 + 4], rbuffer[256 + 4];
int rStatus;
memset (rbuffer, 0x00, 256);
memset (wbuffer, 0x00, 256);
rStatus = CyOpen (deviceNumber, interfaceNum, &handle);
if (rStatus != CY_SUCCESS){
printf ("CY_SPI: Open failed \n");
return rStatus;
}
dataBufferWrite.buffer = wbuffer;
dataBufferRead.buffer = rbuffer;
rStatus = spiWaitForIdle (handle);
if (rStatus){
printf("Error in Waiting for EEPOM active state %d \n", rStatus);
CyClose (handle);
return CY_ERROR_REQUEST_FAILED;
}
printf ("Calling spi write enable \n");
rStatus = spiWriteEnable (handle);
if (rStatus){
printf("Error in setting Write Enable %d \n", rStatus);
CyClose (handle);
return CY_ERROR_REQUEST_FAILED;
}
//Write SPI write command
wbuffer[0] = 0x02;
//SPI flash address
wbuffer[1] = (pageAddress >> 8);
wbuffer[2] = (pageAddress) & 0x00FF;
wbuffer[3] = 0;
printf ("The Data written is ...\n");
printf ("\n--------------------------------------------------------------------\n");
for (rStatus = 4; rStatus < (readWriteLength + 4); rStatus++){
wbuffer[rStatus] = rand() % 256;
printf ("%x ",wbuffer[rStatus]);
}
printf ("\n--------------------------------------------------------------------\n");
dataBufferRead.length = (4 + readWriteLength);
dataBufferWrite.length = (4 + readWriteLength);
rStatus = CySpiReadWrite (handle , &dataBufferRead, &dataBufferWrite, 5000);
if (rStatus != CY_SUCCESS){
CyClose (handle);
printf ("Error in doing SPI data write data Write is %d data read is %d\n" , dataBufferWrite.transferCount,dataBufferRead.transferCount);
return CY_ERROR_REQUEST_FAILED;
}
spiWaitForIdle (handle);
//Write SPI read command
wbuffer[0] = 0x03;
dataBufferRead.length = (4 + readWriteLength);
dataBufferWrite.length = (4 + readWriteLength);
rStatus = CySpiReadWrite (handle, &dataBufferRead, &dataBufferWrite, 5000);
if (rStatus != CY_SUCCESS){
CyClose (handle);
printf ("The Error is %d \n", rStatus);
printf ("Error in doing SPI data write data Write is %d data read is %d\n" , dataBufferWrite.transferCount,dataBufferRead.transferCount);
return CY_ERROR_REQUEST_FAILED;
}
printf ("Data Read back is \n");
printf ("\n---------------------------------------------------------------------\n");
for (rStatus = 4; rStatus < (readWriteLength + 4); rStatus++){
printf ("%x ",rbuffer[rStatus]);
if (rbuffer[rStatus] != wbuffer[rStatus]){
isVerify = false;
}
}
printf ("\n---------------------------------------------------------------------\n");
if (isVerify)
printf ("Data verified successfully \n");
else
printf ("Data corruption occured!!\n");
CyClose (handle);
return CY_SUCCESS;
}
int i2cVerifyData (int deviceNumber, int interfaceNum)
{
CY_DATA_BUFFER dataBufferWrite, dataBufferRead;
CY_HANDLE handle;
int length = 0;
bool isVerify = true;
int loopCount = 100, i;
CY_RETURN_STATUS rStatus;
unsigned char address[2], wbuffer[66], rbuffer[66];
CY_I2C_DATA_CONFIG i2cDataConfig;
memset (wbuffer, 0, 66);
memset (rbuffer, 0, 66);
i2cDataConfig.isStopBit = true;
i2cDataConfig.slaveAddress = 0x51;
rStatus = CyOpen (deviceNumber, interfaceNum, &handle);
if (rStatus != CY_SUCCESS){
printf("CY_I2C: Open failed \n");
return rStatus;
}
loopCount = 100;
length = readWriteLength;
wbuffer[0]= pageAddress;
wbuffer[1] = 0;
dataBufferWrite.buffer = wbuffer;
i2cDataConfig.isStopBit = true;
dataBufferWrite.length = (length + 2);
printf ("\n Data that is written on to i2c ...\n");
printf ("\n-----------------------------------------------------------------\n");
for (i = 2; i < (length +2); i++){
wbuffer[i] = rand() % 256;
printf ("%x ", wbuffer[i]);
}
printf ("\n-----------------------------------------------------------------\n");
rStatus = CyI2cWrite (handle, &i2cDataConfig, &dataBufferWrite, 5000);
if (rStatus != CY_SUCCESS){
printf ("Error in doing i2c write \n");
CyClose (handle);
return -1;
}
//We encountered a error in I2C read repeat the procedure again
//Loop here untill Read vendor command passes
i2cDataConfig.isStopBit = false;
dataBufferWrite.length = 2;
do {
rStatus = CyI2cWrite (handle, &i2cDataConfig, &dataBufferWrite, 5000);
loopCount--;
}while (rStatus != CY_SUCCESS && loopCount != 0);
if (loopCount == 0 && rStatus != CY_SUCCESS){
printf ("Error in sending read command \n");
CyClose (handle);
return -1;
}
dataBufferRead.buffer = rbuffer;
rbuffer[0]= address[0];
rbuffer[1] = 0;
i2cDataConfig.isStopBit = true;
i2cDataConfig.isNakBit = true;
dataBufferRead.length = length;
dataBufferRead.buffer = rbuffer;
memset (rbuffer, 0, 64);
rStatus = CyI2cRead (handle, &i2cDataConfig, &dataBufferRead, 5000);
if (rStatus != CY_SUCCESS){
printf ("Error in doing i2c read ... Error is %d \n", rStatus);
CyClose (handle);
return -1;
}
printf ("\n Data that is read from i2c ...\n");
printf ("\n-----------------------------------------------------------------\n");
for (i = 0; i < length; i++){
printf ("%x ", rbuffer[i]);
if (rbuffer[i] != wbuffer[i + 2]){
isVerify = false;
}
}
printf ("\n-----------------------------------------------------------------\n");
if (!isVerify)
printf ("Data corruption occured ..!!!\n");
else
printf ("Data verified successfully \n");
CyClose (handle);
return CY_SUCCESS;
}
bool isCypressDevice (int deviceNum) {
CY_HANDLE handle;
unsigned char interfaceNum = 0;
unsigned char sig[6];
CY_RETURN_STATUS rStatus;
rStatus = CyOpen (deviceNum, interfaceNum, &handle);
if (rStatus == CY_SUCCESS){
rStatus = CyGetSignature (handle, sig);
if (rStatus == CY_SUCCESS){
CyClose (handle);
return true;
}
else {
CyClose (handle);
return false;
}
}
else
return false;
}
void printListOfDevices (bool isPrint)
{
int i, j, devNum;
int index = 0, numInterfaces, interfaceNum;
char functionality[64];
CY_DEVICE_INFO deviceInfo;
CY_RETURN_STATUS rStatus;
deviceAddedRemoved = false;
CyGetListofDevices (&numDevices);
//printf ("The number of devices is %d \n", numDevices);
for (i = 0; i < numDevices; i++){
for (j = 0; j< CY_MAX_INTERFACES; j++)
glDevice[i].interfaceFunctionality[j] = -1;
}
if (isPrint){
printf ("\n\n---------------------------------------------------------------------------------\n");
printf ("Device Number | VID | PID | INTERFACE NUMBER | FUNCTIONALITY \n");
printf ("---------------------------------------------------------------------------------\n");
}
cyDevices = 0;
for (devNum = 0; devNum < numDevices; devNum++){
rStatus = CyGetDeviceInfo (devNum, &deviceInfo);
interfaceNum = 0;
if (!rStatus)
{
if (!isCypressDevice (devNum)){
continue;
}
strcpy (functionality, "NA");
numInterfaces = deviceInfo.numInterfaces;
glDevice[index].numInterface = numInterfaces;
cyDevices++;
while (numInterfaces){
if (deviceInfo.deviceClass[interfaceNum] == CY_CLASS_VENDOR)
{
glDevice[index].deviceNumber = devNum;
switch (deviceInfo.deviceType[interfaceNum]){
case CY_TYPE_I2C:
glDevice[index].interfaceFunctionality[interfaceNum] = CY_TYPE_I2C;
strcpy (functionality, "VENDOR_I2C");
glDevice[index].isI2c = true;
break;
case CY_TYPE_SPI:
glDevice[index].interfaceFunctionality[interfaceNum] = CY_TYPE_SPI;
strcpy (functionality, "VENDOR_SPI");
glDevice[index].isSpi = true;
break;
default:
strcpy (functionality, "NA");
break;
}
}
else if (deviceInfo.deviceClass[interfaceNum] == CY_CLASS_CDC){
strcpy (functionality, "NA");
}
if (isPrint) {
printf ("%d |%x |%x | %d | %s\n", \
index, \
deviceInfo.vidPid.vid, \
deviceInfo.vidPid.pid, \
interfaceNum, \
functionality \
);
}
interfaceNum++;
numInterfaces--;
}
index++;
}
}
if (isPrint){
printf ("---------------------------------------------------------------------------------\n\n");
}
}