//////////////////////////////////////////////////////////////////////
//
// File: CyAPI.c
//
// Purpose:
// Implement all the functions defined in the CyAPICore.h
//
// Environment:
// User mode
//
// Author: WInScar
//
// ***************** Version 1 *****************
// User: WInScar Date: 27/04/2011 Time: 10:30
// Updated in $/Documents/CyAPI.c
//
// First made
// Include header files:
// 1. CyAPI.h
// Add the most important api functions:
// 1. ezusb_open_device
// 2. ezusb_close_device
// 3. device_control_function
// 4. device_bulk_function
// 5. device_download_hex
// 6. device_version
// 7. get_descriptor_device
// 8. get_descriptor_configuration
// 9. get_descriptor_interface
// 10.get_descriptor_string
// 11.get_current_configuration
// 12.set_current_configuration
// 13.get_current_altsetting
// 14.set_current_altsetting
// 15.bulk_read
// 16.bulk_write
// 17.ezusb_vendor_request
// 18.ezusb_8051_run
// 19.ezusb_8051_hold
//
// Copyright (c) 2011 WInScar.
// See the license agreement for more details.
//
// ***************** Version 2 *****************
// User: WInScar Date: 30/04/2011 Time: 20:01
// Updated in $/Documents/CyAPI.c
//
// Include header file:
// 1. InterlHex.h
//
// Test all the functions in this file.
// Change some of them to make sure that there will not be memory leak.
//
// Copyright (c) 2011 WInScar.
// See the license agreement for more details.
//
//////////////////////////////////////////////////////////////////////
#include "CyAPI.h"
#include "IntelHex.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
unsigned char C2H(char high, char low)
{
unsigned char result = 0x00;
switch(high)
{
case '0': break;
case '1': result += (0x01 << 4);
break;
case '2': result += (0x02 << 4);
break;
case '3': result += (0x03 << 4);
break;
case '4': result += (0x04 << 4);
break;
case '5': result += (0x05 << 4);
break;
case '6': result += (0x06 << 4);
break;
case '7': result += (0x07 << 4);
break;
case '8': result += (0x08 << 4);
break;
case '9': result += (0x09 << 4);
break;
case 'A': result += (0x0A << 4);
break;
case 'B': result += (0x0B << 4);
break;
case 'C': result += (0x0C << 4);
break;
case 'D': result += (0x0D << 4);
break;
case 'E': result += (0x0E << 4);
break;
case 'F': result += (0x0F << 4);
default : break;
}
switch(low)
{
case '0': break;
case '1': result += (0x01);
break;
case '2': result += (0x02);
break;
case '3': result += (0x03);
break;
case '4': result += (0x04);
break;
case '5': result += (0x05);
break;
case '6': result += (0x06);
break;
case '7': result += (0x07);
break;
case '8': result += (0x08);
break;
case '9': result += (0x09);
break;
case 'A': result += (0x0A);
break;
case 'B': result += (0x0B);
break;
case 'C': result += (0x0C);
break;
case 'D': result += (0x0D);
break;
case 'E': result += (0x0E);
break;
case 'F': result += (0x0F);
default : break;
}
return result;
}
void outputConfig(struct usb_config_descriptor *config)
{
printf(" Configuration Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" wTotalLength %5u\n"
" bNumInterfaces %5u\n"
" bConfigurationValue %5u\n"
" iConfiguration %5u\n"
" bmAttributes 0x%02x\n",
config->bLength,
config->bDescriptorType,
config->wTotalLength,
config->bNumInterfaces,
config->bConfigurationValue,
config->iConfiguration,
config->bmAttributes);
return;
}
void outputInterface(struct usb_interface_descriptor *interf)
{
printf(" Interface Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bInterfaceNumber %5u\n"
" bAlternateSetting %5u\n"
" bNumEndpoints %5u\n"
" bInterfaceClass %5u\n"
" bInterfaceSubClass %5u\n"
" bInterfaceProtocol %5u\n"
" iInterface %5u\n",
interf->bLength,
interf->bDescriptorType,
interf->bInterfaceNumber,
interf->bAlternateSetting,
interf->bNumEndpoints,
interf->bInterfaceClass,
interf->bInterfaceSubClass,
interf->bInterfaceProtocol,
interf->iInterface);
return;
}
void outputEndpoint(struct usb_endpoint_descriptor *endpoint)
{
printf(" Endpoint Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bEndpointAddress 0x%02x\n"
" bmAttributes %5u\n"
" wMaxPacketSize 0x%04x\n"
" bInterval %5u\n",
endpoint->bLength,
endpoint->bDescriptorType,
endpoint->bEndpointAddress,
endpoint->bmAttributes,
endpoint->wMaxPacketSize,
endpoint->bInterval);
return;
}
STATUS ezusb_open_device(int *fd)
{
STATUS status = STATUS_FAILED;
if(fd == NULL)
{
printf("File handler needed to be initialized first !\n");
}
*fd = open(DEVICEPATH, O_RDWR);
if(*fd)
{
printf("Device File Open Successfully !\n");
status = STATUS_SUCCESS;
}
else
{
printf("Device File Open Unsuccessfully !\n");
status = STATUS_FAILED;
}
return status;
}
STATUS ezusb_close_device(int *fd)
{
STATUS status = STATUS_FAILED;
if(fd == NULL)
{
printf("File handler needed to be initialized first !\n");
}
if (*fd)
{
printf("Device File Close Successfully !\n");
close(*fd);
status = STATUS_SUCCESS;
}
else
{
printf("Device File Not Exist !\n");
status = STATUS_SUCCESS;
}
return status;
}
STATUS device_download_hex(int fd, char *file_path)
{
STATUS status = STATUS_FAILED;
ezusb_control_data *cd1 = NULL;
ezusb_control_data *cd2 = NULL;
char *line = NULL;
size_t len = 0;
FILE *hex = NULL;
if(fd)
{
cd1 = (ezusb_control_data *)malloc(sizeof(ezusb_control_data));
if (!cd1)
{
printf("Memory is not enough !\n");
goto exit;
}
cd1->value = Vend_Ax_Fx2[0].Address;
cd1->data = Vend_Ax_Fx2[0].Data;
cd1->data_length = Vend_Ax_Fx2[0].Length;
cd1->index = 0x0000;
cd1->timeout = 0;
cd1->actual_length = 0;
status = ioctl(fd,IOCTL_Ezusb_ANCHOR_DOWNLOAD_PRE,cd1);
if(!status)
{
printf("IOCTL_Ezusb_ANCHOR_DOWNLOAD_PRE successful !\n");
hex = fopen(file_path, "r");
if(hex)
{
cd2 = (ezusb_control_data *)malloc(sizeof(ezusb_control_data));
if(!cd2)
{
printf("Memory is not enough !\n");
goto exit1;
}
while(getline(&line,&len,hex) != -1)
{
printf("Get line : %s",line);
if(line[0] != ':') // M index 0
{
printf("This is not a hex file, exit !\n");
goto exit2;
}
else
{
if(line[7] == '0' && line[8] == '0') // RR index 7,8
{
cd2->data_length = C2H(line[1],line[2]); // LL index 1,2
cd2->value = 0x0000;
cd2->value += (C2H(line[3],line[4]) << 8); // AAAA index 3,4,5,6
cd2->value += (C2H(line[5],line[6]) << 0);
cd2->index = 0x0000;
cd2->timeout = 0;
unsigned char *buffer = malloc(cd2->data_length * sizeof(unsigned char));
if(!buffer)
{
printf("Memory is not enough !\n");
goto exit2;
}
int i = 0;
for(;i < (cd2->data_length); i++)
*(buffer+i) = C2H(line[9+i*2],line[10+i*2]);
cd2->data = buffer;
status = ioctl(fd,IOCTL_Ezusb_ANCHOR_DOWNLOAD,cd2);
if(!status) printf("IOCTL_Ezusb_ANCHOR_DOWNLOAD successful !\n");
else printf("IOCTL_Ezusb_ANCHOR_DOWNLOAD unsuccessful !\n");
free(buffer);
}
else if(line[7] == '0' && line[8] == '1')
{
printf("This is a finish record !\n");
break;
}
}
}
}
fclose(hex);
}
else
{
printf("IOCTL_Ezusb_ANCHOR_DOWNLOAD_PRE unsuccessful !\n");
goto exit1;
}
}
else goto exit;
exit3:
if(line) free(line);
exit2:
if(cd2) free(cd2);
exit1:
if(cd1) fr