Docs and fix on the cy-config util
This commit is contained in:
BIN
cy-config.o
Normal file
BIN
cy-config.o
Normal file
Binary file not shown.
@@ -69,24 +69,50 @@ After the installation of TinI/O, you actually don't need to do anything at all
|
|||||||
|
|
||||||
## 3.1 Flashing the chips
|
## 3.1 Flashing the chips
|
||||||
|
|
||||||
|
|
||||||
Cypress CY7C65211 can be flashed only from Windows with a dedicated Cypress utility due to its unique flash file format. Fortunately, after some bargaining with Cypress I got a Linux utility that is licensed under LGPL and free (as speech _and_ beer). It can flash special, decoded versions of flash files that can be produced with a special Windows decoder executable that I can't provide with TinI/O because it's not GPL'd (actually it's not even licensed!) and isn't released to the public (yet). Instead the TinI/O package includes 2 already decoded flash files that should satisfy the needs of a typical user. Their names are:
|
Cypress CY7C65211 can be flashed only from Windows with a dedicated Cypress utility due to its unique flash file format. Fortunately, after some bargaining with Cypress I got a Linux utility that is licensed under LGPL and free (as speech _and_ beer). It can flash special, decoded versions of flash files that can be produced with a special Windows decoder executable that I can't provide with TinI/O because it's not GPL'd (actually it's not even licensed!) and isn't released to the public (yet). Instead the TinI/O package includes 2 already decoded flash files that should satisfy the needs of a typical user. Their names are:
|
||||||
|
|
||||||
- `5-5_decoded.cyusbd`, that provides 5 input and 5 output ports
|
- `5-5_decoded.cyusbd`, that provides 5 input and 5 output ports
|
||||||
- `3-3cs_decoded.cyusbd`, that provides 3 input and 3 output ports, plus a CapSense button with its dedicated input.
|
- `3-3cs_decoded.cyusbd`, that provides 3 input and 3 output ports, plus a CapSense button with its dedicated input.
|
||||||
|
|
||||||
And they provide the following configurations:
|
And they provide the following configurations:
|
||||||
| _parameter_ | _value in `5-5_decoded.cyusbd`_ | _value in `3-3cs_decoded.cyusbd`_ |
|
|
||||||
|-------------|---------------------------------|-----------------------------------|
|
| parameter | value in `5-5_decoded.cyusbd` | value in `3-3cs_decoded.cyusbd` |
|
||||||
|
|----|----|----|
|
||||||
|
| **USB** | | |
|
||||||
| Max. current drawn from USB | 350 mA | 350 mA |
|
| Max. current drawn from USB | 350 mA | 350 mA |
|
||||||
| USB device class | PHDC | PHDC |
|
| USB device class | PHDC | PHDC |
|
||||||
| I/O logic level | LVTTL | LVTTL |
|
| USB ID (vid:pid) | 0x04b4:0004 (Cypress) | 0x04b4:0004 (Cypress) |
|
||||||
| USB Vendor ID | 0x04b4 (Cypress) | 0x04b4 (Cypress) |
|
|
||||||
| USB Product ID | 0x0002 | 0x0002 |
|
|
||||||
| Manufacturer string | TinI/O | TinI/O |
|
| Manufacturer string | TinI/O | TinI/O |
|
||||||
| Product string | 5/5 | 3/3CS |
|
| Product string | 5/5 | 3/3CS |
|
||||||
| UART Tx pin | 5 | 5 |
|
| **Serial** | | |
|
||||||
|
| UART Tx/Rx pins | 5(Tx)/6(Rx) | 5/6 |
|
||||||
|
| UART Speed | 9600 baud | 9600 baud |
|
||||||
|
| UART Data/Stop bits | 8/1 | 8/1 |
|
||||||
|
| UART Parity | None | None |
|
||||||
|
| **I/O** | | |
|
||||||
|
| I/O logic level | LVTTL | LVTTL |
|
||||||
|
| Pin 0 | Input | **RESERVED for CapSense** Should be decoupled to ground by a 2n2 capacitor |
|
||||||
|
| Pin 1 | Input | Input |
|
||||||
|
| Pin 2 | Input | **RESERVED for CapSense** CapSense sense (connect to your button) |
|
||||||
|
| Pin 3 | Input | **RESERVED for CapSense** CapSense output (the output of your button) |
|
||||||
|
| Pin 4 | Input | Input |
|
||||||
|
| Pin 5 | **RESERVED** UART Tx | UART Tx |
|
||||||
|
| Pin 6 | **RESERVED** UART Rx | UART Rx |
|
||||||
|
| Pin 7 | Output | Input |
|
||||||
|
| Pin 8 | Output | Output |
|
||||||
|
| Pin 9 | Output | Output |
|
||||||
|
| Pin 10 | Output | Output |
|
||||||
|
| Pin 11 | Output | Input |
|
||||||
|
_Note: Not all of the information here is neccesary to know when using TinI/O.
|
||||||
|
For a stripped-down version refer to the next chapter, "Using TinI/O"_
|
||||||
|
|
||||||
|
Please notice that flashing of these files isn't the only way of configuring chips. They can be also customized with the Windows utility. The important thing is that you should
|
||||||
|
configure the USB settings as described in the table above.
|
||||||
|
|
||||||
## 3.3 Flashing with the `cy-config` utility
|
## 3.3 Flashing with the `cy-config` utility
|
||||||
|
The flash files I covered in the previous chapter can be flashed with the `cy-config` utility that installs with TinI/O. The utility is text-based. It can be used by running `cy-config`.
|
||||||
|
|
||||||
|
Upon execution,
|
||||||
[chip]: http://www.cypress.com/part/cy7c65211-24ltxi
|
[chip]: http://www.cypress.com/part/cy7c65211-24ltxi
|
||||||
[cylib]: http://github.com/cyrozap/libcyusbserial
|
[cylib]: http://github.com/cyrozap/libcyusbserial
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ default: tinio utils
|
|||||||
|
|
||||||
tinio:
|
tinio:
|
||||||
echo "Building tinio..."
|
echo "Building tinio..."
|
||||||
$(CC) -lcyusbserial main.cpp -o tinio
|
$(CC) -lcyusbserial tinio.cpp -o tinio
|
||||||
|
|
||||||
utils:
|
utils:
|
||||||
$(CC) -lcyusbserial Command_Utility.c -o cy-config
|
$(CC) -lcyusbserial cy-config.c -o cy-config
|
||||||
|
|
||||||
install:
|
install:
|
||||||
echo "Installing tinio and flasher"
|
echo "Installing tinio and flasher"
|
||||||
@@ -16,3 +16,4 @@ install:
|
|||||||
mkdir /usr/share/tinio
|
mkdir /usr/share/tinio
|
||||||
mkdir /usr/share/tinio/flashes
|
mkdir /usr/share/tinio/flashes
|
||||||
cp flashes/* /usr/share/tinio/flashes
|
cp flashes/* /usr/share/tinio/flashes
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +0,0 @@
|
|||||||
/root/projekti/CyUSB/tinio/main.cpp:6:43: fatal error: /usr/local/lib/libcyusbserial.h: Datoteka ali imenik s tem imenom ne obstaja
|
|
||||||
#include "/usr/local/lib/libcyusbserial.h"
|
|
||||||
^
|
|
||||||
compilation terminated.
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
//Tinio - the Tiny I/O tool
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <CyUSBCommon.h>
|
|
||||||
#include <CyUSBSerial.h>
|
|
||||||
|
|
||||||
|
|
||||||
//----ACTUAL CODE BELOW
|
|
||||||
int verifyArgNum(int num) //verifies the number of arguments. minimum is 2
|
|
||||||
{
|
|
||||||
if (num < 2)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int initLib() //initializes the cypress library
|
|
||||||
{
|
|
||||||
if (CyLibraryInit() != CY_SUCCESS) //if the init procedure fails
|
|
||||||
{ //the library may be running.
|
|
||||||
if (CyLibraryExit() != CY_SUCCESS) //try to close the possibly running library
|
|
||||||
{
|
|
||||||
return 1; //if even that fails, abort.
|
|
||||||
}
|
|
||||||
initLib(); //if the library closed gracefully
|
|
||||||
//try to reinitialize
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void usage()
|
|
||||||
{
|
|
||||||
puts("Tinio test build 1");
|
|
||||||
puts("Usage:");
|
|
||||||
//----TODO----//
|
|
||||||
//add a command that prints a
|
|
||||||
//usage summary.
|
|
||||||
}
|
|
||||||
|
|
||||||
int locateDevice() //locate the device and verify it's the right one
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char const *argv[]) {
|
|
||||||
if (!(verifyArgNum(argc)))
|
|
||||||
{
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
initLib();
|
|
||||||
}
|
|
||||||
Binary file not shown.
Binary file not shown.
BIN
tinio/cy-config
Executable file
BIN
tinio/cy-config
Executable file
Binary file not shown.
@@ -30,8 +30,8 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "../../common/header/CyUSBSerial.h"
|
#include "include/CyUSBSerial.h"
|
||||||
#include "../../common/header/CyUSBBootloader.h"
|
#include "include/CyUSBBootloader.h"
|
||||||
|
|
||||||
#define CY_MAX_DEVICES 30
|
#define CY_MAX_DEVICES 30
|
||||||
#define CY_MAX_INTERFACES 4
|
#define CY_MAX_INTERFACES 4
|
||||||
@@ -41,7 +41,7 @@ typedef struct _CY_DEVICE_STRUCT {
|
|||||||
int interfaceFunctionality[CY_MAX_INTERFACES];
|
int interfaceFunctionality[CY_MAX_INTERFACES];
|
||||||
bool isI2c;
|
bool isI2c;
|
||||||
bool isSpi;
|
bool isSpi;
|
||||||
int numInterface;
|
int numInterface;
|
||||||
}CY_DEVICE_STRUCT;
|
}CY_DEVICE_STRUCT;
|
||||||
|
|
||||||
CY_DEVICE_STRUCT *glDevice;
|
CY_DEVICE_STRUCT *glDevice;
|
||||||
@@ -54,331 +54,7 @@ unsigned short pageAddress = -1;
|
|||||||
short readWriteLength = -1;
|
short readWriteLength = -1;
|
||||||
bool deviceAddedRemoved = false;
|
bool deviceAddedRemoved = false;
|
||||||
unsigned char read_buffer[512];
|
unsigned char read_buffer[512];
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int GetCheckSum(unsigned int *buff, unsigned int length)
|
|
||||||
{
|
|
||||||
unsigned int i,val;
|
|
||||||
unsigned int checkSum =0;
|
|
||||||
|
|
||||||
for (i = 0; i < length; i++) // start at 12th byte
|
|
||||||
{
|
|
||||||
checkSum += buff[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
return rStatus;
|
|
||||||
}
|
|
||||||
printListOfDevices (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int index = 0, i, j, userInput;
|
|
||||||
int output;
|
|
||||||
int count=0,h=0,cnt;
|
|
||||||
int size_buffer,size_checksum;
|
|
||||||
FILE *fp=NULL;
|
|
||||||
CY_HANDLE handle;
|
|
||||||
unsigned char buff[516];
|
|
||||||
int silicon_id;
|
|
||||||
int tempSelectedDeviceNum, tempSelectedInterfaceNum;
|
|
||||||
CY_RETURN_STATUS rStatus;
|
|
||||||
signal (SIGUSR1, deviceHotPlug);
|
|
||||||
char src_file[100];
|
|
||||||
char id[4];
|
|
||||||
|
|
||||||
memset(buff,0,sizeof(buff));
|
|
||||||
|
|
||||||
|
|
||||||
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 if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_UART)
|
|
||||||
printf ("UART : \n");
|
|
||||||
else
|
|
||||||
printf (" : NA\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf ("2: Select device...No device selected !!\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 (deviceAddedRemoved == true) {
|
|
||||||
printf ("Device of interest was added/removed .... Print and select from new list\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
selectedDeviceNum = tempSelectedDeviceNum;
|
|
||||||
selectedInterfaceNum = tempSelectedInterfaceNum;
|
|
||||||
|
|
||||||
|
|
||||||
rStatus = CyOpen (selectedDeviceNum,selectedInterfaceNum , &handle);
|
|
||||||
//printf("return status = %d", rStatus);
|
|
||||||
if (rStatus == CY_SUCCESS){
|
|
||||||
//printf("device opened \n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("fail \n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// printf("Please enter file to be opened");
|
|
||||||
|
|
||||||
fp = fopen(argv[1],"rb+");
|
|
||||||
// printf("%s", src_file);
|
|
||||||
rStatus = CyFlashConfigEnable(handle,1);
|
|
||||||
|
|
||||||
if (rStatus == CY_SUCCESS){
|
|
||||||
// printf("Flash is configured");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Manufacturing mode of FLASH is not configured");
|
|
||||||
}
|
|
||||||
// printf("status %d",rStatus);
|
|
||||||
|
|
||||||
if(fp == NULL)
|
|
||||||
{
|
|
||||||
printf("\n fopen() Error!!!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("\n File opened successfully\n");
|
|
||||||
if(sizeof(buff) != fread(buff,1,516,fp))
|
|
||||||
{
|
|
||||||
printf("\n fread() failed\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("\n Bytes successfully read \n");
|
|
||||||
// printf("reached here");
|
|
||||||
|
|
||||||
// silicon_id = *(unsigned int *)buff;
|
|
||||||
|
|
||||||
rStatus=CyGetSiliconID(handle,&silicon_id);
|
|
||||||
if (rStatus == CY_SUCCESS){
|
|
||||||
// printf(" Correct silicon id");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Not correct ID");
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("silicon id %04x,%d",silicon_id,sizeof(silicon_id));
|
|
||||||
id[0]= (silicon_id);
|
|
||||||
id[1]= ((silicon_id >> 8) & 0xFF);
|
|
||||||
id[2]= ((silicon_id >> 16) & 0xFF);
|
|
||||||
id[3]= ((silicon_id >> 24) & 0xFF);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rStatus=CyReadDeviceConfig(handle,&read_buffer);
|
|
||||||
if (rStatus == CY_SUCCESS){
|
|
||||||
// printf(" Got the data");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Not done");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*printf (" 0 %02x, %02x \r \n", id[0],read_buffer[0]);
|
|
||||||
printf (" 1 %02x, %02x \r \n", id[1],read_buffer[1]);
|
|
||||||
printf (" 2 %02x, %02x \r \n", id[2],read_buffer[2]);
|
|
||||||
printf (" 3 %02x, %02x\r \n", id[3],read_buffer[3]);*/
|
|
||||||
|
|
||||||
size_buffer = sizeof(read_buffer);
|
|
||||||
//printf("The size is %d, buff %d", size_buffer,sizeof(buff));
|
|
||||||
|
|
||||||
/*for (i = 4; i < 516; i +=16)
|
|
||||||
{
|
|
||||||
printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
|
||||||
buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8],
|
|
||||||
buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]);
|
|
||||||
}
|
|
||||||
for (i = 0; i < 512; i +=16)
|
|
||||||
{
|
|
||||||
printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
|
||||||
read_buffer[i], read_buffer[i+1], read_buffer[i+2], read_buffer[i+3], read_buffer[i+4], read_buffer[i+5], read_buffer[i+6],
|
|
||||||
read_buffer[i+7], read_buffer[i+8],
|
|
||||||
read_buffer[i+9], read_buffer[i+10], read_buffer[i+11], read_buffer[i+12], read_buffer[i+13], read_buffer[i+14], read_buffer[i+15]);
|
|
||||||
}*/
|
|
||||||
memcpy (&buff[4], read_buffer, 28);
|
|
||||||
|
|
||||||
size_checksum= GetCheckSum((unsigned int *)(&buff[16]), 125);
|
|
||||||
// printf("The checksum size is %d",size_checksum);
|
|
||||||
|
|
||||||
buff[12]= (size_checksum & 0xFF);
|
|
||||||
buff[13]= ((size_checksum >> 8) & 0xFF);
|
|
||||||
buff[14]= ((size_checksum >> 16) & 0xFF);
|
|
||||||
buff[15]= ((size_checksum >> 24) & 0xFF);
|
|
||||||
|
|
||||||
// printf("checksum 0x%08x\n", size_checksum);
|
|
||||||
/* for (i = 4; i < 516; i +=16)
|
|
||||||
{
|
|
||||||
printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
|
||||||
buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8],
|
|
||||||
buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// if(((id[0] == ffffffA1) || (id[0] == ffffffA2) || (id[0] == ffffffA3)) && (id[1] == 08))
|
|
||||||
if((silicon_id == 0x08A1) || (silicon_id == 0x08A2) || (silicon_id == 0x08A3))
|
|
||||||
{
|
|
||||||
|
|
||||||
rStatus= CyWriteDeviceConfig(handle,&buff[4]);
|
|
||||||
if (rStatus == CY_SUCCESS){
|
|
||||||
printf(" Programming Flash is done");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Not done");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("wrong silicon id");
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
printf("\n File stream closed \n");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rStatus= CyClose(handle);
|
|
||||||
if (rStatus == CY_SUCCESS){
|
|
||||||
//printf("Device closed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Not closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
exitApp = true;
|
|
||||||
CyLibraryExit ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}while (exitApp == false);
|
|
||||||
free (glDevice);
|
|
||||||
}
|
|
||||||
bool isCypressDevice (int deviceNum) {
|
|
||||||
CY_HANDLE handle;
|
|
||||||
unsigned char interfaceNum = 0;
|
|
||||||
unsigned char sig[6];
|
|
||||||
int op;
|
|
||||||
CY_RETURN_STATUS rStatus;
|
|
||||||
rStatus = CyOpen (deviceNum, interfaceNum, &handle);
|
|
||||||
//op= libusb_detach_kernel_driver(handle,0);
|
|
||||||
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)
|
void printListOfDevices (bool isPrint)
|
||||||
{
|
{
|
||||||
int index_i = 0, index_j = 0, i, j, countOfDevice = 0, devNum;
|
int index_i = 0, index_j = 0, i, j, countOfDevice = 0, devNum;
|
||||||
@@ -386,15 +62,15 @@ void printListOfDevices (bool isPrint)
|
|||||||
bool set1 = false;
|
bool set1 = false;
|
||||||
|
|
||||||
unsigned char deviceID[CY_MAX_DEVICES];
|
unsigned char deviceID[CY_MAX_DEVICES];
|
||||||
unsigned char functionality[64];
|
char functionality[64];
|
||||||
CY_DEVICE_INFO deviceInfo;
|
CY_DEVICE_INFO deviceInfo;
|
||||||
CY_DEVICE_CLASS deviceClass[CY_MAX_INTERFACES];
|
CY_DEVICE_CLASS deviceClass[CY_MAX_INTERFACES];
|
||||||
CY_DEVICE_TYPE deviceType[CY_MAX_INTERFACES];
|
CY_DEVICE_TYPE deviceType[CY_MAX_INTERFACES];
|
||||||
CY_RETURN_STATUS rStatus;
|
CY_RETURN_STATUS rStatus;
|
||||||
|
|
||||||
deviceAddedRemoved = false;
|
deviceAddedRemoved = false;
|
||||||
CyGetListofDevices (&numDevices);
|
CyGetListofDevices ((UINT8 *)&numDevices);
|
||||||
//printf ("The number of devices is %d \n", numDevices);
|
//printf ("The number of devices is %d \n", numDevices);
|
||||||
for (i = 0; i < numDevices; i++){
|
for (i = 0; i < numDevices; i++){
|
||||||
for (j = 0; j< CY_MAX_INTERFACES; j++)
|
for (j = 0; j< CY_MAX_INTERFACES; j++)
|
||||||
glDevice[i].interfaceFunctionality[j] = -1;
|
glDevice[i].interfaceFunctionality[j] = -1;
|
||||||
@@ -435,14 +111,14 @@ void printListOfDevices (bool isPrint)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strcpy (functionality, "NA");
|
strcpy (functionality, "NA");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (deviceInfo.deviceClass[interfaceNum] == CY_CLASS_CDC){
|
else if (deviceInfo.deviceClass[interfaceNum] == CY_CLASS_CDC){
|
||||||
strcpy (functionality, "NA");
|
strcpy (functionality, "NA");
|
||||||
}
|
}
|
||||||
if (isPrint) {
|
if (isPrint) {
|
||||||
printf ("%d |%x |%x | %d | %s\n", \
|
printf ("%d |%x |%x | %d | %s\n", \
|
||||||
index, \
|
index, \
|
||||||
deviceInfo.vidPid.vid, \
|
deviceInfo.vidPid.vid, \
|
||||||
deviceInfo.vidPid.pid, \
|
deviceInfo.vidPid.pid, \
|
||||||
@@ -462,3 +138,328 @@ void printListOfDevices (bool isPrint)
|
|||||||
printf("Cydevices %d",cyDevices);
|
printf("Cydevices %d",cyDevices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deviceHotPlug () {
|
||||||
|
|
||||||
|
CY_RETURN_STATUS rStatus;
|
||||||
|
deviceAddedRemoved = true;
|
||||||
|
selectedDeviceNum = -1;
|
||||||
|
selectedInterfaceNum = -1;
|
||||||
|
printf ("Device of interest Removed/Added \n");
|
||||||
|
rStatus = CyGetListofDevices ((UINT8 *)&numDevices);
|
||||||
|
if (rStatus != CY_SUCCESS) {
|
||||||
|
printf ("CY:Error in Getting List of Devices: Error NO:<%d> \n", rStatus);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printListOfDevices (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int GetCheckSum(unsigned int *buff, unsigned int length)
|
||||||
|
{
|
||||||
|
unsigned int i,val;
|
||||||
|
unsigned int checkSum =0;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) // start at 12th byte
|
||||||
|
{
|
||||||
|
checkSum += buff[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int index = 0, i, j, userInput;
|
||||||
|
int output;
|
||||||
|
int count=0,h=0,cnt;
|
||||||
|
int size_buffer,size_checksum;
|
||||||
|
FILE *fp=NULL;
|
||||||
|
CY_HANDLE handle;
|
||||||
|
unsigned char buff[516];
|
||||||
|
int silicon_id;
|
||||||
|
int tempSelectedDeviceNum, tempSelectedInterfaceNum;
|
||||||
|
CY_RETURN_STATUS rStatus;
|
||||||
|
//signal (SIGUSR1, deviceHotPlug);
|
||||||
|
char src_file[100];
|
||||||
|
char id[4];
|
||||||
|
|
||||||
|
memset(buff,0,sizeof(buff));
|
||||||
|
|
||||||
|
|
||||||
|
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 ((UINT8 *)&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 if (glDevice[selectedDeviceNum].interfaceFunctionality[selectedInterfaceNum] == CY_TYPE_UART)
|
||||||
|
printf ("UART : \n");
|
||||||
|
else
|
||||||
|
printf (" : NA\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf ("2: Select device...No device selected !!\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 (deviceAddedRemoved == true) {
|
||||||
|
printf ("Device of interest was added/removed .... Print and select from new list\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
selectedDeviceNum = tempSelectedDeviceNum;
|
||||||
|
selectedInterfaceNum = tempSelectedInterfaceNum;
|
||||||
|
|
||||||
|
|
||||||
|
rStatus = CyOpen (selectedDeviceNum,selectedInterfaceNum , &handle);
|
||||||
|
//printf("return status = %d", rStatus);
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
//printf("device opened \n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("fail \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// printf("Please enter file to be opened");
|
||||||
|
|
||||||
|
fp = fopen(argv[1],"rb+");
|
||||||
|
// printf("%s", src_file);
|
||||||
|
rStatus = CyFlashConfigEnable(handle,1);
|
||||||
|
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
// printf("Flash is configured");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Manufacturing mode of FLASH is not configured");
|
||||||
|
}
|
||||||
|
// printf("status %d",rStatus);
|
||||||
|
|
||||||
|
if(fp == NULL)
|
||||||
|
{
|
||||||
|
printf("\n fopen() Error!!!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("\n File opened successfully\n");
|
||||||
|
if(sizeof(buff) != fread(buff,1,516,fp))
|
||||||
|
{
|
||||||
|
printf("\n fread() failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("\n Bytes successfully read \n");
|
||||||
|
// printf("reached here");
|
||||||
|
|
||||||
|
// silicon_id = *(unsigned int *)buff;
|
||||||
|
|
||||||
|
rStatus=CyGetSiliconID(handle,(UINT32 *)&silicon_id);
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
// printf(" Correct silicon id");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Not correct ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("silicon id %04x,%d",silicon_id,sizeof(silicon_id));
|
||||||
|
id[0]= (silicon_id);
|
||||||
|
id[1]= ((silicon_id >> 8) & 0xFF);
|
||||||
|
id[2]= ((silicon_id >> 16) & 0xFF);
|
||||||
|
id[3]= ((silicon_id >> 24) & 0xFF);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rStatus=CyReadDeviceConfig(handle, (UCHAR *)&read_buffer);
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
// printf(" Got the data");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Not done");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*printf (" 0 %02x, %02x \r \n", id[0],read_buffer[0]);
|
||||||
|
printf (" 1 %02x, %02x \r \n", id[1],read_buffer[1]);
|
||||||
|
printf (" 2 %02x, %02x \r \n", id[2],read_buffer[2]);
|
||||||
|
printf (" 3 %02x, %02x\r \n", id[3],read_buffer[3]);*/
|
||||||
|
|
||||||
|
size_buffer = sizeof(read_buffer);
|
||||||
|
//printf("The size is %d, buff %d", size_buffer,sizeof(buff));
|
||||||
|
|
||||||
|
/*for (i = 4; i < 516; i +=16)
|
||||||
|
{
|
||||||
|
printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
|
buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8],
|
||||||
|
buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 512; i +=16)
|
||||||
|
{
|
||||||
|
printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
|
read_buffer[i], read_buffer[i+1], read_buffer[i+2], read_buffer[i+3], read_buffer[i+4], read_buffer[i+5], read_buffer[i+6],
|
||||||
|
read_buffer[i+7], read_buffer[i+8],
|
||||||
|
read_buffer[i+9], read_buffer[i+10], read_buffer[i+11], read_buffer[i+12], read_buffer[i+13], read_buffer[i+14], read_buffer[i+15]);
|
||||||
|
}*/
|
||||||
|
memcpy (&buff[4], read_buffer, 28);
|
||||||
|
|
||||||
|
size_checksum= GetCheckSum((unsigned int *)(&buff[16]), 125);
|
||||||
|
// printf("The checksum size is %d",size_checksum);
|
||||||
|
|
||||||
|
buff[12]= (size_checksum & 0xFF);
|
||||||
|
buff[13]= ((size_checksum >> 8) & 0xFF);
|
||||||
|
buff[14]= ((size_checksum >> 16) & 0xFF);
|
||||||
|
buff[15]= ((size_checksum >> 24) & 0xFF);
|
||||||
|
|
||||||
|
// printf("checksum 0x%08x\n", size_checksum);
|
||||||
|
/* for (i = 4; i < 516; i +=16)
|
||||||
|
{
|
||||||
|
printf("\n%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
|
buff[i], buff[i+1], buff[i+2], buff[i+3], buff[i+4], buff[i+5], buff[i+6], buff[i+7], buff[i+8],
|
||||||
|
buff[i+9], buff[i+10], buff[i+11], buff[i+12], buff[i+13], buff[i+14], buff[i+15]);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// if(((id[0] == ffffffA1) || (id[0] == ffffffA2) || (id[0] == ffffffA3)) && (id[1] == 08))
|
||||||
|
if((silicon_id == 0x08A1) || (silicon_id == 0x08A2) || (silicon_id == 0x08A3))
|
||||||
|
{
|
||||||
|
|
||||||
|
rStatus= CyWriteDeviceConfig(handle,&buff[4]);
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
printf(" Programming Flash is done");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Not done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("wrong silicon id");
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
printf("\n File stream closed \n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rStatus= CyClose(handle);
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
//printf("Device closed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Not closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
exitApp = true;
|
||||||
|
CyLibraryExit ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}while (exitApp == false);
|
||||||
|
free (glDevice);
|
||||||
|
}
|
||||||
|
bool isCypressDevice (int deviceNum) {
|
||||||
|
CY_HANDLE handle;
|
||||||
|
unsigned char interfaceNum = 0;
|
||||||
|
unsigned char sig[6];
|
||||||
|
int op;
|
||||||
|
CY_RETURN_STATUS rStatus;
|
||||||
|
rStatus = CyOpen (deviceNum, interfaceNum, &handle);
|
||||||
|
//op= libusb_detach_kernel_driver(handle,0);
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
rStatus = CyGetSignature (handle, sig);
|
||||||
|
if (rStatus == CY_SUCCESS){
|
||||||
|
CyClose (handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CyClose (handle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
a.out
|
|
||||||
@@ -15,7 +15,7 @@ bool valueToWrite=false, writeFlag=false, readFlag=false, exitFlag=false, expert
|
|||||||
// those vars are to be used with locateDevice function
|
// those vars are to be used with locateDevice function
|
||||||
const uint8_t maxDevs = 16; // 16 connected devices should be enough...
|
const uint8_t maxDevs = 16; // 16 connected devices should be enough...
|
||||||
const CY_VID_PID deviceVidPid{UINT16(0x04b4),
|
const CY_VID_PID deviceVidPid{UINT16(0x04b4),
|
||||||
UINT16(0x0002)}; // the id for the chip
|
UINT16(0x0004)}; // the id for the chip
|
||||||
uint8_t deviceNumList[maxDevs];
|
uint8_t deviceNumList[maxDevs];
|
||||||
uint8_t deviceCount;
|
uint8_t deviceCount;
|
||||||
CY_DEVICE_INFO deviceInfoList[maxDevs];
|
CY_DEVICE_INFO deviceInfoList[maxDevs];
|
||||||
@@ -171,16 +171,15 @@ int evalErrors(const CY_RETURN_STATUS error) { // evaluates errors, duh?
|
|||||||
int locateDevice() // locate the device and verify it's the right one
|
int locateDevice() // locate the device and verify it's the right one
|
||||||
{
|
{
|
||||||
// printf("Locating devices..."); //debug, not needed
|
// printf("Locating devices..."); //debug, not needed
|
||||||
try {
|
|
||||||
CY_RETURN_STATUS retVal;
|
CY_RETURN_STATUS retVal;
|
||||||
retVal = CyGetDeviceInfoVidPid(
|
retVal = CyGetDeviceInfoVidPid( //--searches for the device with given VID/PID
|
||||||
deviceVidPid, deviceNumList,
|
deviceVidPid, deviceNumList, //--and stores them into lists
|
||||||
deviceInfoList, //--searches for the device with given VID/PID
|
deviceInfoList, //--refer to lib docs for more info
|
||||||
&deviceCount, maxDevs); //--and stores them into lists
|
&deviceCount, maxDevs);
|
||||||
//--refer to lib docs for more info
|
|
||||||
throw retVal; // throws the return value of the func
|
|
||||||
} catch (CY_RETURN_STATUS errVal) {
|
int r = evalErrors(retVal); // evaluate the errors
|
||||||
int r = evalErrors(errVal); // evaluate the errors
|
|
||||||
if (r != 0) { // exit on error
|
if (r != 0) { // exit on error
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -192,7 +191,6 @@ int locateDevice() // locate the device and verify it's the right one
|
|||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int attachDevices() { // loops through devices and attaches them to handles
|
int attachDevices() { // loops through devices and attaches them to handles
|
||||||
|
|||||||
Reference in New Issue
Block a user