#ifdef __VISUALC__ #include #define SF_DEBUG_USB 0 #endif #include #include "SURConstants.h" #include "SiUSBDevice.h" #include "SiI2CDevice.h" #include //------------------------------------------------------------------------------ // USBDevice.cpp // // SILAB, Phys. Inst Bonn, HK // // USB devices associated to slbusb.sys device driver // // History: // 04.03.02 added generic I2C functions // 03.10.01 modifiedadded init functions (StartDriver, StopDriver) // for TUSBDeviceManager // 31.08.01 added latch and adc access for mqube tracker //------------------------------------------------------------------------------ int HexToInt2(std::string hString) { int val; val=strtol(hString.c_str(),(char **)NULL,16); return val; } void SwapBytes(unsigned char *data, int size) { unsigned char temp; for (int i = 0; i < size; i++) { temp = 0; for (unsigned char j = 0; j < 8; j++) { temp |= (unsigned char)(((data[i] & (0x01 << j)) >> j) << (7 - j)); } data[i] = temp; } } #ifndef CF__LINUX void ShowLastError(char *)//msg) { void * lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); // Display the string. // MessageBox( NULL, (const char *)lpMsgBuf, msg, MB_OK|MB_ICONINFORMATION ); OutputDebugString((LPCSTR) lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); } #endif //--------------------------------------------------------------------------- const char PIPE_TYPE_STRINGS[4][5] = { "CTRL", "ISO", "BULK", "INT" }; const char PIPE_DIRECTION[2][4] = { "OUT", "IN" }; // Constructor: initializes member variables and the USB device itself TUSBDevice::TUSBDevice(int index):TI2CMaster(), TSPIMaster(), TXilinxChip(true) { USBDeviceHandle = INVALID_HANDLE_VALUE; // handle to the driver pvDescriptorBuffer = NULL; // pvStringBuffer = NULL; // DescString = NULL; Desc = NULL; // pointer to descriptor information DeviceDriverIndex = index; std::stringstream stream; #ifdef CF__LINUX stream << "silab" << DeviceDriverIndex; #else stream << "slbusb-" << DeviceDriverIndex; #endif std::string arraystring = stream.str(); DeviceDriverName = arraystring; // device name associated within the driver started = false; configured = false; // firmware active Name = ""; Id = 0; FwVer = -1; m_mutex = new QMutex(); } // opens driver for SiLab-USB controller (slbusb.sys) // device name MUST be "slbusb-n", where n is the number of the connected SLBUSB // device -> e.g. "slbusb-0" bool TUSBDevice::StartDriver() { #ifdef CF__LINUX AnsiString CompleteDeviceName = "/dev/" + DeviceDriverName ; if (SF_DEBUG_USB>0) printf("***> TUSBDevice::StartDriver():: device : %s \n",CompleteDeviceName.c_str()); if ((fdUSBDeviceHandle = open (CompleteDeviceName.c_str(), O_RDWR)) < 0) { printf("!!!! StartDriver():: error:: Close USB device : %s \n",CompleteDeviceName.c_str()); close(fdUSBDeviceHandle); USBDeviceHandle = INVALID_HANDLE_VALUE; return false; } USBDeviceHandle=&fdUSBDeviceHandle; #else std::string CompleteDeviceName = "\\\\.\\" + DeviceDriverName ; USBDeviceHandle = CreateFile(CompleteDeviceName.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (USBDeviceHandle == INVALID_HANDLE_VALUE) { CloseHandle(USBDeviceHandle); USBDeviceHandle = INVALID_HANDLE_VALUE; return false; } #endif Init(); // fsv LoadHexFileToEeprom("bulkloop.hex"); started = true; return true; } void TUSBDevice::Init() { #ifdef CF__LINUX if(SF_DEBUG_USB>0) { printf("***> TUSBDevice::Init() ===========================================================\n"); printf("***> TUSBDevice::Init() == B o a r d I N I T ==\n"); printf("***> TUSBDevice::Init() ===========================================================\n"); } if (!GetDeviceDescriptor()) { printf("TUSBDevice::Init() error \n"); return; } if(SF_DEBUG_USB>0) printf(" VendorId = 0x%x ProductId = 0x%x\n",Desc->idVendor,Desc->idProduct); #else GetDeviceDescriptor(); #endif VendorId = Desc->idVendor; ProductId = Desc->idProduct; GetPipeInfo(); if ((ProductId & 0x0200) || (ProductId == 0x8613)) // FX2LP device { sur_control_pipe = SUR_CONTROL_PIPE_FX; sur_data_out_pipe = SUR_DATA_OUT_PIPE_FX; sur_data_in_pipe = SUR_DATA_IN_PIPE_FX; cpu_cs_reg = CPUCS_REG_FX; eeprom_user_data_offset = EEPROM_USER_DATA_OFFSET_FX; eeprom_mfg_addr = EEPROM_MFG_ADDR_FX; eeprom_name_addr = EEPROM_NAME_ADDR_FX; eeprom_id_addr = EEPROM_ID_ADDR_FX; eeprom_liac_addr = EEPROM_LIAC_ADDR_FX; xp_conf_port_cfg = PORTACFG_FX; xp_conf_port_oe = OEA_FX; xp_conf_port_rd = IOA_FX; xp_conf_port_wr = IOA_FX; is_fx = true; } else { sur_control_pipe = SUR_CONTROL_PIPE; sur_data_out_pipe = SUR_DATA_OUT_PIPE; sur_data_in_pipe = SUR_DATA_IN_PIPE; cpu_cs_reg = CPUCS_REG; eeprom_user_data_offset = EEPROM_USER_DATA_OFFSET; eeprom_mfg_addr = EEPROM_MFG_ADDR; eeprom_name_addr = EEPROM_NAME_ADDR; eeprom_id_addr = EEPROM_ID_ADDR; eeprom_liac_addr = EEPROM_LIAC_ADDR; xp_conf_port_cfg = PORTCCFG; xp_conf_port_oe = OEC; xp_conf_port_rd = PINSC; xp_conf_port_wr = OUTC; is_fx = false; } Id = -1; FwVer = -1; DeviceClass = 0xff; if(pInterface->NumberOfPipes != 0) // firmware present { bool got_strdesc = GetStringDescriptor(); if (!ReadIDFromEEPROM()) Id = -1; if (!ReadFirmwareVersion()) FwVer = -1; if (!ReadNameFromEEPROM()) { if (got_strdesc) Name = std::string(DescString[2]); else Name = "Unknown"; } if (!ReadDeviceClassFromEEPROM()) DeviceClass = 0xff; configured = true; } else { Name = "not available"; Id = DeviceDriverIndex + 100; } ClkGen = new TI2CClockGen((TI2CMaster *) this, CG_FREF); if(!ClkGen->isOk) { delete ClkGen; ClkGen = NULL; } #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf(" < TUSBDevice::Init() Id=%d Name=%s DeviceClass=0x%x\n" ,Id,Name.c_str(),DeviceClass); if (SF_DEBUG_USB>0) { printf(" < TUSBDevice::Init() ============================================================\n"); printf(" < TUSBDevice::Init() == E N D Board I N I T ==\n"); printf(" < TUSBDevice::Init() ============================================================\n"); } #endif } bool TUSBDevice::DeviceAvailable() { bool status; #ifdef CF__LINUX int fd; AnsiString CompleteDeviceName = "/dev/" + DeviceDriverName ; if (SF_DEBUG_USB>0) printf("***> TUSBDevice::DeviceAvailable():: name: %s status =",CompleteDeviceName.c_str()); if ((fd = open (CompleteDeviceName.c_str(), O_RDWR)) < 0) { status = false; if (SF_DEBUG_USB>0) printf(" not found\n"); } else { status = true; close(fd); if (SF_DEBUG_USB>0) printf(" OK\n"); } #else std::string CompleteDeviceName = "\\\\.\\" + DeviceDriverName ; HANDLE TestHandle = CreateFile(CompleteDeviceName.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (TestHandle == INVALID_HANDLE_VALUE) status = false; else { status = true; CloseHandle(TestHandle); } #endif return status; } bool TUSBDevice::StopDriver() { if(started) { #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::StopDriver() \n"); if (USBDeviceHandle == INVALID_HANDLE_VALUE) // oops! { return false; } else close(fdUSBDeviceHandle); #else if (USBDeviceHandle == INVALID_HANDLE_VALUE) // oops! { return false; } else { if (!CloseHandle(USBDeviceHandle)) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::StopDriver()"); #endif return false; } } #endif } started = false; return true; } // destructor: closes device driver and frees memory TUSBDevice::~TUSBDevice() { if(ClkGen != NULL) delete ClkGen; if(configured) // firmware present { for (unsigned char sIndex = 0; sIndex < MAX_STRING_INDEX; sIndex++) // number of strings to read { if (pvStringBuffer[sIndex] != NULL) free(pvStringBuffer[sIndex]); if (DescString[sIndex] != NULL) free(DescString[sIndex]); } } if(pvDescriptorBuffer != NULL) free(pvDescriptorBuffer); StopDriver(); delete m_mutex; } bool TUSBDevice::ReadIDFromEEPROM() { EEPROM_ID_STRUCT idstr; void *ptr; bool status; std::string str; #ifdef CF__LINUX if (SF_DEBUG_USB>2) printf("***> TUSBDevice::ReadIDFromEEPROM() \n"); #endif ptr = &idstr; status = ReadEEPROM(eeprom_id_addr, (unsigned char*)ptr, EEPROM_ID_SIZE); if (!status) { #if (SHOW_HIGHER_LEVEL_ERRORS) MessageBox( NULL, "ERROR", "TUSBDevice::ReadIDFromEEPROM", MB_OK|MB_ICONINFORMATION ); #endif return false; } #ifdef CF__LINUX Id = atoi(idstr.content); if (SF_DEBUG_USB>0) printf(" < TUSBDevice::ReadIDFromEEPROM() Id=%d Str=%s \n",Id,idstr.content); #else str = std::string(idstr.content); str = str.substr(0, idstr.length); Id = atoi(str.c_str()); #endif return true; } bool TUSBDevice::ReadNameFromEEPROM() { EEPROM_NAME_STRUCT namestr; bool status; void *ptr; std::string str; #ifdef CF__LINUX if (SF_DEBUG_USB>2) printf("***> TUSBDevice::ReadNameFromEEPROM() \n"); #endif ptr = &namestr; status = ReadEEPROM(eeprom_name_addr, (unsigned char*)ptr, EEPROM_NAME_SIZE); if (!status) { #if (SHOW_HIGHER_LEVEL_ERRORS) MessageBox( NULL, "ERROR", "TUSBDevice::ReadNameFromEEPROM", MB_OK|MB_ICONINFORMATION ); #endif return false; } #ifdef CF__LINUX str = namestr.content; Name.assign(str,0,namestr.length); if (SF_DEBUG_USB>0) printf(" TUSBDevice::ReadNameFromEEPROM() Name=%s \n",Name.c_str()); #else str = std::string(namestr.content); Name = str.substr(0, namestr.length); #endif return true; } bool TUSBDevice::WriteIDToEEPROM(int id) { EEPROM_ID_STRUCT idstr; void *ptr; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteIDToEEPROM(id=%d) \n",id); sprintf(idstr.content, "%d", id); idstr.length = min(strlen(idstr.content), (unsigned int)EEPROM_ID_SIZE-1); #else sprintf(idstr.content, "%d", id); idstr.length = min(strlen(idstr.content), (unsigned int)EEPROM_ID_SIZE-1); #endif ptr = &idstr; status = WriteEEPROM(eeprom_id_addr, (unsigned char*)ptr, (unsigned int)EEPROM_ID_SIZE); if (!status) { #if (SHOW_HIGHER_LEVEL_ERRORS) MessageBox( NULL, "ERROR", "TUSBDevice::WriteIDToEEPROM", MB_OK|MB_ICONINFORMATION ); #endif return false; } return true; } bool TUSBDevice::WriteNameToEEPROM(const char* Name) { EEPROM_NAME_STRUCT namestr; void *ptr; bool status; std::string newName(Name); strcpy(namestr.content, newName.c_str()); #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteNameToEEPROM(%s) \n",newName.c_str()); namestr.length = min(newName.Length(), EEPROM_NAME_SIZE-1); #else namestr.length = min(newName.length(), EEPROM_NAME_SIZE-1); #endif ptr = &namestr; status = WriteEEPROM(eeprom_name_addr, (unsigned char*)ptr, EEPROM_NAME_SIZE); if (!status) { #if (SHOW_HIGHER_LEVEL_ERRORS) MessageBox( NULL, "ERROR", "TUSBDevice::WriteNameToEEPROM", MB_OK|MB_ICONINFORMATION ); #endif return false; } return true; } bool TUSBDevice::WriteDeviceClassToEEPROM(unsigned char dc) { bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteDeviceClassToEEPROM(dc=0x%x) \n",dc); #endif status = WriteEEPROM(eeprom_liac_addr, &dc, (unsigned int)EEPROM_LIAC_SIZE); if (!status) { #if (SHOW_HIGHER_LEVEL_ERRORS) MessageBox( NULL, "ERROR", "TUSBDevice::WriteDeviceClassToEEPROM", MB_OK|MB_ICONINFORMATION ); #endif return false; } return true; } bool TUSBDevice::ReadDeviceClassFromEEPROM() { bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ReadDeviceClassFromEEPROM() \n"); #endif status = ReadEEPROM(eeprom_liac_addr, &DeviceClass, EEPROM_LIAC_SIZE); if (!status) { #if (SHOW_HIGHER_LEVEL_ERRORS) MessageBox( NULL, "ERROR", "TUSBDevice::ReadDeviceClassFromEEPROM", MB_OK|MB_ICONINFORMATION ); #endif return false; } #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf(" TUSBDevice::ReadDeviceClassFromEEPROM() DeviceClass=0x%x\n",DeviceClass); #endif return true; } int TUSBDevice::GetId() { ReadIDFromEEPROM(); return Id; } const char* TUSBDevice::GetName() { ReadNameFromEEPROM(); return Name.c_str(); } int TUSBDevice::GetClass() { ReadDeviceClassFromEEPROM(); return DeviceClass; } int TUSBDevice::GetFWVersion() { // ReadFirmwareVersion(); return FwVer; } const char* TUSBDevice::GetEndpointInfo() { return PipeInfoString.c_str(); } // GetPipeInfo: reads information about pipes bool TUSBDevice::GetPipeInfo() { BOOL result = false; unsigned long nBytes; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::GetPipeInfo() \n"); #endif if (USBDeviceHandle != NULL) {// Perform the Get-Descriptor IOCTL result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_GET_PIPE_INFO, NULL, 0, InterfaceInfo, sizeof(InterfaceInfo), &nBytes, NULL); } if (result) { pInterface = (PUSBD_INTERFACE_INFORMATION) InterfaceInfo; // FIXME pPipe = pInterface->Pipes; PipeInfoString = ""; std::stringstream stream; if (SF_DEBUG_USB>0) printf("Number of pipes: %ld \n",pInterface->NumberOfPipes); #ifdef CF__LINUX for (int i = 0; i < (int) pInterface->NumberOfPipes; i++) { // BUGBUG stream << " Pipe: " << i << " Type: " << PIPE_TYPE_STRINGS[pPipe[i].PipeType] << " Endpoint: " << (int)(pPipe[i].EndpointAddress & 0x0F) << " " << PIPE_DIRECTION[0x01 & (pPipe[i].EndpointAddress >> 7)] << " MaxPktSize: " << (int)pPipe[i].MaximumPacketSize << std::endl; } if (SF_DEBUG_USB>0) printf("%s",stream.str().c_str()); #endif PipeInfoString = stream.str(); } else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::GetPipeInfo()"); #endif return false; } return true; } #ifdef CF__LINUX // GetDeviceDescriptor: reads configuration data bool TUSBDevice::ResetCPU() { bool result; unsigned long nBytes; if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ResetCPU() \n"); if (USBDeviceHandle != NULL) result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_RESET_CPU, pvDescriptorBuffer, sizeof (Usb_Device_Descriptor), pvDescriptorBuffer, sizeof (Usb_Device_Descriptor), &nBytes, NULL); else return false; return true; } #endif // GetDeviceDescriptor: reads configuration data bool TUSBDevice::GetDeviceDescriptor() { BOOL result = false; unsigned long nBytes; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::GetDeviceDescriptor() ... "); #endif // Get some memory, plus some guardband area if ((pvDescriptorBuffer = malloc(sizeof (Usb_Device_Descriptor) + 128)) == NULL) { #if (SHOW_BASIC_ERRORS) MessageBox(NULL, "malloc failed", "TUSBDevice::GetDeviceDescriptor", MB_OK | MB_ICONEXCLAMATION); #endif return false; } if (USBDeviceHandle != NULL) result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_GET_DEVICE_DESCRIPTOR, pvDescriptorBuffer, sizeof (Usb_Device_Descriptor), pvDescriptorBuffer, sizeof (Usb_Device_Descriptor), &nBytes, NULL); else return false; if (result) { Desc = (Usb_Device_Descriptor*) pvDescriptorBuffer; return true; } else { //#if (SHOW_BASIC_ERRORS) // ShowLastError("TUSBDevice::GetDeviceDescriptor()"); //#endif return false; } } // GetStringDescriptor: reads more configuration data bool TUSBDevice::GetStringDescriptor() { BOOL result = false; unsigned long nBytes; unsigned char ulLength; pUsb_String_Descriptor pSD[MAX_STRING_INDEX]; // array of pointer to string descriptor GET_STRING_DESCRIPTOR_IN input; #ifdef CF__LINUX GET_STRING_DESCRIPTOR_IN *input2; if (SF_DEBUG_USB>3) printf("***> TUSBDevice::GetStringDescriptor() \n"); #endif input.LanguageId = 27; // ignored anyway for (unsigned char sIndex = 0; sIndex < MAX_STRING_INDEX; sIndex++) // number of strings to read { input.Index = sIndex; DescString[sIndex] = NULL; if((pvStringBuffer[sIndex] = malloc (sizeof (Usb_String_Descriptor) + 128)) == NULL) { #if (SHOW_BASIC_ERRORS) MessageBox(NULL, "malloc failed", "TUSBDevice::GetStringDescriptor", MB_OK | MB_ICONEXCLAMATION); #endif return false; } #ifdef CF__LINUX input2 = (GET_STRING_DESCRIPTOR_IN *)pvStringBuffer[sIndex]; input2->LanguageId = 27; // ignored anyway input2->Index = sIndex; #endif #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf(" GetStringDescriptor(): IOCTL=%ld \n",IOCTL_SLBUSB_GET_STRING_DESCRIPTOR); #endif // Get the first unsigned chars of the descriptor to determine the size of the entire descriptor. if (USBDeviceHandle != NULL) { result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_GET_STRING_DESCRIPTOR, &input, sizeof (GET_STRING_DESCRIPTOR_IN), pvStringBuffer[sIndex], sizeof (Usb_String_Descriptor), &nBytes, NULL); } else // fatal { #if (SHOW_BASIC_ERRORS) ShowLastError(" ERROR: USBDeviceHandle :: TUSBDevice::GetStringDescriptor() \n"); #endif return false; } #ifdef CF__LINUX pSD[sIndex] = (pUsb_String_Descriptor) pvStringBuffer[sIndex]; DescString[sIndex] = (char *) malloc(pSD[sIndex]->bLength+1); DescString[sIndex][0]=0; strncpy (DescString[sIndex],(char*)pSD[sIndex]->bString,pSD[sIndex]->bLength); if (SF_DEBUG_USB>0) printf(" sIndex=%d, sz=%2d, Str=%s \n",sIndex ,pSD[sIndex]->bLength,DescString[sIndex]); continue; #endif if (result != TRUE) // this will happen with no string defined { free (pvStringBuffer[sIndex]); // ??? #if (SHOW_BASIC_ERRORS) ShowLastError("oops"); #endif #ifdef CF__LINUX printf(" ERROR: GetStringDescriptor() \n"); #endif return false; } ulLength = ((pUsb_String_Descriptor)pvStringBuffer[sIndex])->bLength; if (ulLength != 0) // This will happen with empty string { // Now get the entire descriptor if((pvStringBuffer[sIndex] = realloc (pvStringBuffer[sIndex], ulLength)) == NULL) { #if (SHOW_BASIC_ERRORS) MessageBox(NULL, "realloc failed", "TUSBDevice::GetStringDescriptor", MB_OK | MB_ICONEXCLAMATION); #endif return false; } #ifdef CF__LINUX input2 = (GET_STRING_DESCRIPTOR_IN *)pvStringBuffer[sIndex]; input2->LanguageId = 27; // ignored anyway input2->Index = sIndex; if (SF_DEBUG_USB>3) printf(" GetStringDescriptor(2)::iStr=%d, IOCTL_SLBUSB_GET_STRING_DESCRIPTOR=0x%x\n ",sIndex , (unsigned int) IOCTL_SLBUSB_GET_STRING_DESCRIPTOR); #endif result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_GET_STRING_DESCRIPTOR, &input, ulLength, pvStringBuffer[sIndex], ulLength, &nBytes, NULL); if (result == TRUE) { // parse string decriptor pSD[sIndex] = (pUsb_String_Descriptor) pvStringBuffer[sIndex]; DescString[sIndex] = (char *) malloc((pSD[sIndex]->bLength)/2); for(int i=0; i<((pSD[sIndex]->bLength/2)-1) /*&& ibString[i]); } } // free (pvStringBuffer); } // do loop index return true; } // LoadFirmwareFromFile: loads *.bix files (memory images) to internal 8051 RAM // limited to 8k of program data, no access to external RAM or EEPROM bool TUSBDevice::LoadFirmwareFromFile(std::string FileName) { #define MAX_FILE_SIZE (1024*16) // 16 k for FX2LP devices FILE *fp; unsigned char *buffer; int numread; unsigned long nBytes; BOOL result = false; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::LoadFirmwareFromFile(%s)\n",FileName.c_str()); #endif buffer = new unsigned char[MAX_FILE_SIZE]; if ((fp = fopen(FileName.c_str(),"rb")) == NULL) { #ifdef CF__LINUX AnsiString Msg = "File not found." + FileName; if (SF_DEBUG_USB>0) printf("!!!! File not found:(%s)\n",FileName.c_str()); #else std::stringstream stream; std::string ss; stream << "File " << FileName << " not found."; ss = stream.str(); MessageBox(NULL, ss.c_str(), "TUSBDevice::DownloadFirmwareFromFile", MB_OK | MB_ICONEXCLAMATION); #endif return false; } numread = fread(buffer,sizeof(unsigned char),MAX_FILE_SIZE,fp); fclose(fp); configured = false; Hold8051(); //printf("test: LoadFirmwareFromFile::USB_ANCHOR_DOWNLOAD:: %IOCTL=0x%x buffer=%d, size=%d\n" // ,IOCTL_SLBUSB_ANCHOR_DOWNLOAD, buffer[0], numread); // load to internal RAM result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_ANCHOR_DOWNLOAD, buffer, numread, NULL, 0, &nBytes, NULL); Run8051(); // ??? need to do this twice to enumerate when device is plugged in ??? // Hold8051(); // Run8051(); // ??? need to do this twice to enumerate when device is plugged in ??? // CyclePort(); // force re-enumeration delete[] buffer; if (result) { return true; } else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::LoadFirmwareFromFile"); #endif return false; } } // WriteBulkEndpoint: writes outData with size of outPacketSize // to OUT endpoint (nEndPoint) bool TUSBDevice::WriteBulkEndpoint(int nPipe, unsigned char *outData, int outPacketSize) { BOOL result = false; unsigned long nBytes; BULK_TRANSFER_CONTROL bulkControl; bulkControl.pipeNum = nPipe; // Perform the BULK OUT #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::WriteBulkEndpoint(pipe=0x%x size=%d)\n",nPipe,outPacketSize); #endif result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_BULK_WRITE, &bulkControl, sizeof(BULK_TRANSFER_CONTROL), outData, outPacketSize, &nBytes, NULL); if (!result) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteBulkEndpoint"); #endif #ifdef CF__LINUX printf("!!!> ERROR=%d TUSBDevice::WriteBulkEndpoint(pipe=0x%x size=%d)\n",result,nPipe,outPacketSize); #endif return false; } return true; } // ReadBulkEndpoint: reads inData with size of inPacketSize (max 64 unsigned char) // from IN endpoint (nEndPoint) bool TUSBDevice::ReadBulkEndpoint(int nPipe, unsigned char *inData, int inPacketSize, int *nBytesRead) { BOOL result = false; unsigned long nBytes; BULK_TRANSFER_CONTROL bulkControl; bulkControl.pipeNum = nPipe; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ReadBulkEndpoint(pipe=0x%x p-size=%d) ...." ,nPipe,inPacketSize); #endif // Perform the BULK IN result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_BULK_READ, &bulkControl, sizeof(BULK_TRANSFER_CONTROL), inData, inPacketSize, &nBytes, NULL); #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf(" actual len=%ld\n",nBytes); #endif if (!result) { #ifdef CF__LINUX printf("!!!> ERROR=%d TUSBDevice::ReadBulkEndpoint(pipe=0x%x p-size=%d) \n",result,(int)nPipe,inPacketSize); #endif #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadBulkEndpoint"); #endif *nBytesRead = 0; return false; } *nBytesRead = (int) nBytes; return true; } // VendorOrClassRequest: control transfer to endpoint 0 // transmission of 8 unsigned char setup data (setupdat[8]) with an // optional data phase: // // setupdata name meaning // 0 bmRequestType Request Type, Direction, and Recepient // 1 bRequest The actual request // 2 wValueL Word-size value, varies according to bRequest // 3 wValueH // 4 wIndexL Word-size field, varies according to bRequest // 5 wIndexH // 6 wLengthL Number of unsigned chars to transfer if there is a data phase // 7 wLengthH bool TUSBDevice::VendorOrClassRequest(VENDOR_OR_CLASS_REQUEST_CONTROL *MyRequest, unsigned char *data, unsigned short length) { unsigned long nBytes; BOOL result = false; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::VendorOrClassRequest \n"); #endif result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_VENDOR_OR_CLASS_REQUEST, MyRequest, sizeof(VENDOR_OR_CLASS_REQUEST_CONTROL), data, length, (unsigned long *)&nBytes, 0); if ((result == TRUE) && (nBytes == (unsigned long)length)) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::VendorOrClassRequest"); #endif return false; } } // VendorRequest: similar to VendorOrClassRequest, used for one unsigned char transfers bool TUSBDevice::VendorRequest(VENDOR_REQUEST_IN *MyRequest) { unsigned long nBytes; BOOL result = false; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::VendorRequest, size=%ld \n",sizeof(VENDOR_REQUEST_IN)); #endif result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_VENDOR_REQUEST, MyRequest, sizeof(VENDOR_REQUEST_IN), &(MyRequest->bData), 1, (unsigned long *)&nBytes, 0); //printf("***> TUSBDevice::VendorRequest, result=%d TRUE=%d\n",result,TRUE); // if ((result == TRUE) && (nBytes == 1)) if (result == TRUE) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::VendorRequest"); #endif return false; } } bool TUSBDevice::SilabUsbRequest(PSILAB_USB_REQUEST psur, unsigned char* data, int biglength) { bool status; int dataleft; int dataptr; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::SilabUsbRequest (BIG) len=%d MAX_SUR_DATA_SIZE=%d\n" ,biglength,MAX_SUR_DATA_SIZE); #endif if ((biglength == 0) || (biglength <= MAX_SUR_DATA_SIZE)) return SilabUsbRequest(psur, data); else { dataleft = biglength; dataptr = 0; do // transfer 64 k blocks { psur->length = MAX_SUR_DATA_SIZE; status = SilabUsbRequest(psur,(unsigned char*)(data + dataptr)); if (!status) return false; dataleft -= MAX_SUR_DATA_SIZE; dataptr += MAX_SUR_DATA_SIZE; } while (dataleft >= MAX_SUR_DATA_SIZE); psur->length = dataleft; status = SilabUsbRequest(psur, (unsigned char*)(data + dataptr)); } return status; } bool TUSBDevice::SilabUsbRequest(PSILAB_USB_REQUEST psur, unsigned char* data) { unsigned short ptr = 0; // data offset in current transfer int blocksize; // data size in current transfer unsigned long dataleft = psur->length; // initial requested data size unsigned long MaxTransferSize; int nBytes; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::SilabUsbRequest() size=%d MAX_SUR_DATA_SIZE=%d\n",(int)dataleft, (int)MAX_SUR_DATA_SIZE); #endif unsigned char buffer[10]; int buffersize; buffer[0] = psur->type; buffer[1] = psur->dir; if(is_fx) { buffer[2] = (unsigned char)(0xff & psur->addr); buffer[3] = (unsigned char)(0xff & (psur->addr >> 8)); buffer[4] = (unsigned char)(0xff & (psur->addr >> 16)); buffer[5] = (unsigned char)(0xff & (psur->addr >> 24)); buffer[6] = (unsigned char)(0xff & psur->length); buffer[7] = (unsigned char)(0xff & (psur->length >> 8)); buffer[8] = (unsigned char)(0xff & (psur->length >> 16)); buffer[9] = (unsigned char)(0xff & (psur->length >> 24)); buffersize = 10; } else { buffer[2] = (unsigned char)(0xff & psur->addr); buffer[3] = (unsigned char)(0xff & (psur->addr >> 8)); buffer[4] = (unsigned char)(0xff & psur->length); buffer[5] = (unsigned char)(0xff & (psur->length >> 8)); buffersize = 6; } #ifdef CF__LINUX if (SF_DEBUG_USB>5) printf("---| TUSBDevice::SilabUsbRequest() sur_control_pipe=0x%x, bufsize=%d\n" ,sur_control_pipe,buffersize); #endif // send setup data to bulk endpoint 1 to initialize data transfer status = WriteBulkEndpoint(sur_control_pipe, buffer, buffersize); if (!status) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::SilabUsbRequest(setup phase)"); #endif return false; } // Remark: MAXTRANSFERSIZE is *NOT* the endpoints maximum *packet* size. It is // the size of a transfer buffer which is handled by the USBD. In fact a single IO_CTL // request can handle larger blocks than 64 unsigned char maximum endpoint packet size. // MAXTRANSFERSIZE is controlled by the USBD. Get value with GetPipeInfo() #ifdef CF__LINUX_2 //-- not used if(psur->dir == SUR_DIR_OUT) // write transfer MaxTransferSize = pPipe[sur_data_out_pipe].MaximumPacketSize; else MaxTransferSize = pPipe[sur_data_in_pipe].MaximumPacketSize; #else if(psur->dir == SUR_DIR_OUT) // write transfer MaxTransferSize = pPipe[sur_data_out_pipe].MaximumPacketSize;//MaximumTransferSize; else MaxTransferSize = pPipe[sur_data_in_pipe].MaximumPacketSize;//MaximumTransferSize; #endif #ifdef CF__LINUX if (SF_DEBUG_USB>5) printf("---| TUSBDevice::SilabUsbRequest() DIR=%d MaxTransferSize=MaxPacketSize=%d Len=%d\n" ,(int)psur->dir,(int)MaxTransferSize,(int)dataleft); #endif while(dataleft > 0) { if (dataleft < MaxTransferSize) // less than buffer size blocksize = dataleft; else // more than buffer size blocksize = MaxTransferSize; // now do the transfer if(psur->dir == SUR_DIR_OUT) // write transfer status &= WriteBulkEndpoint(sur_data_out_pipe, (unsigned char *) (data + ptr), blocksize); else status &= ReadBulkEndpoint(sur_data_in_pipe, (unsigned char *) (data + ptr), blocksize, &nBytes); ptr += blocksize; // increment data pointer for next transfer dataleft -= blocksize; // remaining data fraction } if (status && (dataleft == 0)) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::SilabUsbRequest(data phase)"); #endif return false; } } bool TUSBDevice::WriteInterrupt(unsigned char * Data) // write EP4 { bool status; status = WriteBulkEndpoint(SUR_DIRECT_OUT_PIPE, Data, 4); // set here length of char data array, minimum is 4 to avoid errors if (!status) { #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteInterrupt, error in WriteBulkEndpoint \n"); #else OutputDebugStringA("TUSBDevice::WriteInterrupt, error in WriteBulkEndpoint"); #endif return false; } return true; } bool TUSBDevice::ReadInterrupt(unsigned char * Data) // read EP5 { int nBytes; bool status; status = ReadBulkEndpoint(SUR_DIRECT_IN_PIPE, Data, 4, &nBytes); // set here length of char data array, set to at least 4 to avoid errors if (!status) { #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ReadInterrupt, error in ReadBulkEndpoint \n"); #else OutputDebugStringA("TUSBDevice::ReadInterrupt, error in ReadBulkEndpoint"); #endif return false; } return true; } bool TUSBDevice::FastByteWrite(unsigned char *data) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::FastByteWrite() \n"); #endif sur.type = SUR_TYPE_GPIFBYTE; sur.dir = SUR_DIR_OUT; sur.addr = 0; sur.length = 1; // send setup data to bulk endpoint 1 to initialize data transfer status = WriteBulkEndpoint(sur_control_pipe, (unsigned char *)&sur, 10); status &= WriteBulkEndpoint(sur_data_out_pipe, data, 1); if (!status) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::SilabUsbRequest(setup phase)"); #endif return false; } return true; } bool TUSBDevice::FastByteRead(unsigned char *data) { SILAB_USB_REQUEST sur; int nBytesRead; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::FastByteRead() \n"); #endif sur.type = SUR_TYPE_GPIFBYTE; sur.dir = SUR_DIR_IN; sur.addr = 0; sur.length = 1; // send setup data to bulk endpoint 1 to initialize data transfer status = WriteBulkEndpoint(sur_control_pipe, (unsigned char *)&sur, 10); status &= ReadBulkEndpoint(sur_data_in_pipe, data, 1, &nBytesRead); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::FastBytewrite"); #endif return false; } } bool TUSBDevice::FastBlockWrite(unsigned char *data, int length) { int addr = 0; unsigned char buffer[10]; unsigned char buffersize = 10; int ptr = 0; int blocksize; // data size in current transfer int dataleft = length; // initial requested data size bool status; int MaxTransferSize; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::FastBlockWrite(len=%d) \n",length); #endif if (!length) return false; buffer[0] = SUR_TYPE_GPIFBLOCK; buffer[1] = SUR_DIR_OUT; buffer[2] = (unsigned char)(0xff & addr); buffer[3] = (unsigned char)(0xff & (addr >> 8)); buffer[4] = (unsigned char)(0xff & (addr >> 16)); buffer[5] = (unsigned char)(0xff & (addr >> 24)); buffer[6] = (unsigned char)(0xff & length); buffer[7] = (unsigned char)(0xff & (length >> 8)); buffer[8] = (unsigned char)(0xff & (length >> 16)); buffer[9] = (unsigned char)(0xff & (length >> 24)); MaxTransferSize = (int)pPipe[SUR_DATA_FASTOUT_PIPE].MaximumTransferSize - 1; // send setup data to bulk endpoint 0 to initialize data transfer status = WriteBulkEndpoint(sur_control_pipe, buffer, buffersize); if (!status) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::FastBlockWrite(setup phase)"); #endif return false; } while(dataleft > 0) { if (dataleft < MaxTransferSize) // less than buffer size blocksize = dataleft; else // more than buffer size blocksize = MaxTransferSize; // now do the transfer status &= WriteBulkEndpoint(SUR_DATA_FASTOUT_PIPE, (unsigned char *) (data + ptr), blocksize); ptr += blocksize; // increment data pointer for next transfer dataleft -= blocksize; // remaining data fraction } if (status && (dataleft == 0)) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::FastBlockwrite"); #endif return false; } } bool TUSBDevice::FastBlockRead(unsigned char *data, int length) { int addr = 0; unsigned char buffer[10]; unsigned char buffersize = 10; int ptr = 0; int blocksize; // data size in current transfer int dataleft = length; // initial requested data size int MaxTransferSize; int nBytesRead; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::FastBlockRead(len=%d) \n",length); #endif if (!length) return false; MaxTransferSize = pPipe[SUR_DATA_FASTIN_PIPE].MaximumTransferSize - 1; // bug in driver??? /* buffer[0] = SUR_TYPE_GPIFBLOCK; buffer[1] = SUR_DIR_IN; buffer[2] = (unsigned char)(0xff & (addr)); buffer[3] = (unsigned char)(0xff & ((addr) >> 8)); buffer[4] = (unsigned char)(0xff & ((addr) >> 16)); buffer[5] = (unsigned char)(0xff & ((addr) >> 24)); buffer[6] = (unsigned char)(0xff & length); buffer[7] = (unsigned char)(0xff & (length >> 8)); buffer[8] = (unsigned char)(0xff & (length >> 16)); buffer[9] = (unsigned char)(0xff & (length >> 24)); status = WriteBulkEndpoint(sur_control_pipe, buffer, buffersize); if (!status) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::FastBlockRead(setup phase)"); #endif return false; } */ while(dataleft > 0) { if (dataleft < MaxTransferSize) // less than buffer size blocksize = dataleft; else // more than buffer size blocksize = MaxTransferSize; { // send setup data to bulk endpoint 0 to initialize data transfer buffer[0] = SUR_TYPE_GPIFBLOCK; buffer[1] = SUR_DIR_IN; buffer[2] = (unsigned char)(0xff & (addr+ptr)); buffer[3] = (unsigned char)(0xff & ((addr+ptr) >> 8)); buffer[4] = (unsigned char)(0xff & ((addr+ptr) >> 16)); buffer[5] = (unsigned char)(0xff & ((addr+ptr) >> 24)); buffer[6] = (unsigned char)(0xff & blocksize); buffer[7] = (unsigned char)(0xff & (blocksize >> 8)); buffer[8] = (unsigned char)(0xff & (blocksize >> 16)); buffer[9] = (unsigned char)(0xff & (blocksize >> 24)); status = WriteBulkEndpoint(sur_control_pipe, buffer, buffersize); if (!status) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::FastBlockRead(setup phase)"); #endif return false; } // now do the transfer #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::FastBlockRead blocksize=%d MaxTransferSize=%d dataleft=%d\n" ,blocksize,MaxTransferSize,dataleft); if (SF_DEBUG_USB>3) printf("***> TUSBDevice::FastBlockRead **> do the transfer <**\n"); #endif status &= ReadBulkEndpoint(SUR_DATA_FASTIN_PIPE, (unsigned char *) (data + ptr), blocksize, &nBytesRead); ptr += nBytesRead; // increment data pointer for next transfer dataleft -= nBytesRead; // remaining data fraction if (status == false) break; } } // -- while(dataleft > 0) if (status && (dataleft == 0)) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::FastBlockRead"); #endif return false; } } bool TUSBDevice::WriteEEPROM(unsigned short address, unsigned char *Data, unsigned short Length) { #define EEPROM_PAGESIZE 64 SILAB_USB_REQUEST sur; int temp_count; bool status=false; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteEEPROM(adr=0x%x len=%d) \n",address,Length); #endif sur.type = SUR_TYPE_EEPROM; sur.dir = SUR_DIR_OUT; sur.addr = address; sur.length = Length; if (Length < EEPROM_PAGESIZE) { status = SilabUsbRequest(&sur, Data); } else { temp_count = Length; sur.length = EEPROM_PAGESIZE; while (temp_count > 0) { status = SilabUsbRequest(&sur, Data); temp_count -= EEPROM_PAGESIZE; sur.length = min(EEPROM_PAGESIZE, temp_count); sur.addr += EEPROM_PAGESIZE; Data += EEPROM_PAGESIZE; } } if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteEEPROM"); #endif return false; } } bool TUSBDevice::ReadEEPROM(unsigned short address, unsigned char *Data, unsigned short Length) { SILAB_USB_REQUEST sur; int temp_count; bool status=false; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ReadEEPROM(addr=0x%x, len=%d) \n",address,Length); #endif sur.type = SUR_TYPE_EEPROM; sur.dir = SUR_DIR_IN; sur.addr = address; sur.length = Length; if (Length <= MAX_USB_PACKET_SIZE) status = SilabUsbRequest(&sur, Data); else { temp_count = Length; sur.length = MAX_USB_PACKET_SIZE; while(temp_count > 0) { status = SilabUsbRequest(&sur, Data); temp_count -= MAX_USB_PACKET_SIZE; sur.length = min(MAX_USB_PACKET_SIZE, temp_count); sur.addr += MAX_USB_PACKET_SIZE; Data += MAX_USB_PACKET_SIZE; } } if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadEEPROM"); #endif return false; } } bool TUSBDevice::WriteExternal(unsigned short address, unsigned char *Data, int Length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::WriteExternal(adr=0x%x len=%d) \n",address,Length); #endif sur.type = SUR_TYPE_EXTERNAL; sur.dir = SUR_DIR_OUT; sur.addr = address; sur.length = Length; if (Length <= 0xffff) status = SilabUsbRequest(&sur, Data); else status = SilabUsbRequest(&sur, Data, Length); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteExternal"); #endif return false; } } bool TUSBDevice::ReadExternal(unsigned short address, unsigned char *Data, int Length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ReadExternal(adr=0x%x len=%d) \n",address,Length); #endif sur.type = SUR_TYPE_EXTERNAL; sur.dir = SUR_DIR_IN; sur.addr = address; sur.length = Length; if (Length <= 0xffff) status = SilabUsbRequest(&sur, Data); else status = SilabUsbRequest(&sur, Data, Length); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadExternal"); #endif return false; } } /* bool TUSBDevice::WriteFIFO(unsigned char *Data, unsigned short Length) { SILAB_USB_REQUEST sur; bool status; sur.type = SUR_TYPE_FIFO; sur.dir = SUR_DIR_OUT; sur.addr = 0; sur.length = Length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteFIFO"); #endif return false; } } unsigned short TUSBDevice::ReadFIFO(unsigned char *Data, unsigned short Length) { SILAB_USB_REQUEST sur; bool status; sur.type = SUR_TYPE_FIFO; sur.dir = SUR_DIR_IN; sur.addr = 0; sur.length = Length; status = SilabUsbRequest(&sur, Data); if (status) return sur.nBytes; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadFIFO"); #endif return 0; } } */ unsigned short TUSBDevice::ReadFIFO(unsigned char *data, int size) { int nBytes; bool status; unsigned char buffer[10]; int buffersize; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ReadFIFO(size=%d) \n",size); #endif buffer[0] = SUR_TYPE_FIFO; buffer[1] = SUR_DIR_IN; if(is_fx) { buffer[2] = 0; buffer[3] = 0; buffer[4] = 0; buffer[5] = 0; buffer[6] = (unsigned char)(0xff & size); buffer[7] = (unsigned char)(0xff & (size >> 8)); buffer[8] = (unsigned char)(0xff & (size >> 16)); buffer[9] = (unsigned char)(0xff & (size >> 24)); buffersize = 10; } else { buffer[2] = 0; buffer[3] = 0; buffer[4] = (unsigned char)(0xff & size); buffer[5] = (unsigned char)(0xff & (size >> 8)); buffersize = 6; } status = WriteBulkEndpoint(sur_control_pipe, buffer, buffersize); status &= ReadBulkEndpoint(sur_data_in_pipe, data, size, &nBytes); if(!status) return 0; else return nBytes; } bool TUSBDevice::Write8051(unsigned short address, unsigned char *Data, unsigned short Length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::Write8051(adr=0x%x len=%d) \n",address,Length); #endif sur.type = SUR_TYPE_8051; sur.dir = SUR_DIR_OUT; sur.addr = address; sur.length = Length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::Write8051"); #endif return false; } } bool TUSBDevice::Read8051(unsigned short address, unsigned char *Data, unsigned short Length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::Read8051(adr=0x%x len=%d) \n",address,Length); #endif sur.type = SUR_TYPE_8051; sur.dir = SUR_DIR_IN; sur.addr = address; sur.length = Length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::Read8051"); #endif return false; } } bool TUSBDevice::SetBit8051(unsigned short address, unsigned char mask, bool set) { unsigned char portreg; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::SetBit8051(adr=0x%x mask=0x%x \n",address,mask); #endif if (!Read8051(address, &portreg)) return false; portreg = set ? portreg | mask : portreg & (unsigned char) ~mask; /* if (!set) portreg &= (unsigned char) ~mask; else portreg |= mask; */ if(!Write8051(address, &portreg)) return false; return true; } bool TUSBDevice::GetBit8051(unsigned short address, unsigned char mask, bool& get) { unsigned char portreg; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::GetBit8051(adr=0x%x mask=0x%x \n",address,mask); #endif if (!Read8051(address, &portreg)) return false; get = ((portreg & mask) != 0); return true; } bool TUSBDevice::WriteSerial(unsigned char *Data, unsigned short Length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteSerial(len=%d) \n",Length); #endif sur.type = SUR_TYPE_SERIAL; sur.dir = SUR_DIR_OUT; sur.addr = 0; sur.length = Length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteSerial"); #endif return false; } } bool TUSBDevice::ReadSerial( unsigned char *Data, unsigned short Length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ReadSerial(len=%d) \n",Length); #endif sur.type = SUR_TYPE_SERIAL; sur.dir = SUR_DIR_IN; sur.addr = 0; sur.length = Length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadSerial"); #endif return false; } } bool TUSBDevice::I2CAck() { unsigned char dummy; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::I2CAck() \n"); #endif if (is_fx) Read8051(I2CS_FX, &dummy, 1); else Read8051(I2CS, &dummy, 1); return ((dummy & I2CS_NACK) != 0); } bool TUSBDevice::ReadI2C(unsigned char SlaveAdd, unsigned char *data, unsigned short length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ReadI2C(add=0x%x len=%d) \n",SlaveAdd,length); #endif sur.type = SUR_TYPE_I2C; sur.dir = SUR_DIR_IN; sur.addr = SlaveAdd; sur.length = length; status = SilabUsbRequest(&sur, data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadI2C"); #endif return false; } } bool TUSBDevice::WriteI2C(unsigned char SlaveAdd, unsigned char *data, unsigned short length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::WriteI2C(add=0x%x len=%d) \n",SlaveAdd,length); #endif sur.type = SUR_TYPE_I2C; sur.dir = SUR_DIR_OUT; sur.addr = SlaveAdd; sur.length = length; status = SilabUsbRequest(&sur, data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteI2C"); #endif return false; } } bool TUSBDevice::WriteI2Cnv(unsigned char SlaveAdd, unsigned char *data, unsigned short length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteI2Cnv(len=%d) \n",length); #endif sur.type = SUR_TYPE_I2C_NV; sur.dir = SUR_DIR_OUT; sur.addr = SlaveAdd; sur.length = length; status = SilabUsbRequest(&sur, data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteI2Cnv"); #endif return false; } } bool TUSBDevice::WriteLatch(unsigned char *Data) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteLatch() \n"); #endif sur.type = SUR_TYPE_LATCH; sur.dir = SUR_DIR_OUT; sur.addr = 0; sur.length = 1; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteLatch"); #endif return false; } } bool TUSBDevice::WriteCommand(unsigned char *Data, unsigned short lenght) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteCommand() \n"); #endif sur.type = SUR_TYPE_CMD; sur.dir = SUR_DIR_OUT; sur.addr = 0; sur.length = lenght; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteCommand"); #endif return false; } } void TUSBDevice::InitSPI() { // enable special function port lines for SPI use // // SDI PA7/RxD1out // SDO PB2/RxD1 // SCK PB3/TxD1 // #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::InitSPI() \n"); #endif // PORTACFG |= bmBIT7; SetBit8051(PORTACFG, bmBIT7, 1); // PORTBCFG |= bmBIT2 | bmBIT3; SetBit8051(PORTBCFG, bmBIT2 | bmBIT3, 1); // configure /SHUTDOWN pin // // /SHDN PA6/RxD0out // PORTACFG &= bmBIT6; SetBit8051(PORTACFG, bmBIT6, 0); SetBit8051(OUTA, bmBIT6, 0); SetBit8051(OEA, bmBIT6, 1); // address lines for chip select // // ADD0 PB0 // ADD1 PB1 // ADD2 PB4 // ADD3 PB5 // ADD4 PB6 // // ADC chip select // /CSADC PB7 // PORTBCFG &= ~(bmBIT0 | bmBIT1 | bmBIT4 | bmBIT5 | bmBIT6 | bmBIT7); SetBit8051(PORTBCFG, bmBIT0 | bmBIT1 | bmBIT4 | bmBIT5 | bmBIT6 | bmBIT7, 0); // OUTB &= ~(bmBIT0 | bmBIT1 | bmBIT4 | bmBIT5 | bmBIT6); SetBit8051(OUTB, bmBIT0 | bmBIT1 | bmBIT4 | bmBIT5 | bmBIT6, 0); // OUTB |= bmBIT7; // de-select ADC SetBit8051(OUTB, bmBIT7, 1); // de-select ADC // OEB |= bmBIT0 | bmBIT1 | bmBIT4 | bmBIT5 | bmBIT6 | bmBIT7; // enable outputs SetBit8051(OEB, bmBIT0 | bmBIT1 | bmBIT4 | bmBIT5 | bmBIT6 | bmBIT7, 1); // enable outputs // enable UART for SPI functionality // // *** remember: UART sends and receives LSB first *** // *** transmit on falling edge, receive on rising edge *** // *** half duplex communication, can't send and receive at the same time *** // // SCON1 // bit7 serial mode bit0 // bit6 serial mode bit1 (see EZ-USB C-31) // bit5 multiprocessor enable // bit4 receive enable // bit3 9th data bit transmitted (mode 2 and 3 only) // bit2 9th data bit received (mode 2 and 3 only) // bit1 transmit interrupt flag // bit0 receive interrupt flag // SCON1 = 0x13; // mode 0, baud 24MHz/12, enable receive // unsigned char temp = 0x13; SetBit8051(SCON1, 0x13, 1); // mode 0, baud 24MHz/12, enable receive } bool TUSBDevice::WriteSPI(int add, unsigned char *Data, unsigned short length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteSPI(len=%d) \n",length); #endif sur.type = SUR_TYPE_SPI; sur.dir = SUR_DIR_OUT; sur.addr = add; sur.length = length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteSPI"); #endif return false; } } bool TUSBDevice::ReadSPI(int add, unsigned char *Data, unsigned short length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ReadSPI(len=%d) \n",length); #endif sur.type = SUR_TYPE_SPI; sur.dir = SUR_DIR_IN; sur.addr = add; sur.length = length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadSPI"); #endif return false; } } bool TUSBDevice::ReadADC(unsigned char address, int *Data) { SILAB_USB_REQUEST sur; bool status; unsigned char bData[2]; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ReadADC() \n"); #endif sur.type = SUR_TYPE_ADC; sur.dir = SUR_DIR_IN; sur.addr = address; sur.length = 2; status = SilabUsbRequest(&sur, bData); *Data = (unsigned short) (bData[1] + (bData[0] << 8)); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadADC"); #endif return false; } } bool TUSBDevice::ReadAdcSPI(unsigned char address, unsigned char *Data) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ReadAdcSPI() \n"); #endif sur.type = SUR_TYPE_ADCSPI; sur.dir = SUR_DIR_IN; sur.addr = address; sur.length = 4; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadAdcSPI"); #endif return false; } } bool TUSBDevice::ReadFirmwareVersion() { SILAB_USB_REQUEST sur; bool status; unsigned char Data[3]; sur.type = SUR_TYPE_FWVER; sur.dir = SUR_DIR_IN; sur.addr = 0; sur.length = 2; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ReadFirmwareVersion() \n"); #endif status = SilabUsbRequest(&sur, Data); Data[2] = '\0'; if (status) { FwVer = atoi((char*)Data); #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf(" TUSBDevice::ReadFirmwareVersion() VERSION=%d \n",FwVer); #endif return true; } else { #if (SHOW_HIGHER_LEVEL_ERRORS) ShowLastError("TUSBDevice::ReadFirmewareVersion"); #endif return false; } } // ResetPipe: // bool TUSBDevice::ResetPipe(int pipenum) { BOOL result = false; unsigned long nBytes; DWORD iBuf = pipenum; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ResetPipe(pipenum=%d) \n",pipenum); #endif #ifdef CF__LINUX puts("not yet!!! ResetPipe USB_RESETPIPE "); #else result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_RESETPIPE, // IOCTL_SLBUSB_ABORTPIPE, &iBuf, sizeof(iBuf), NULL, 0, &nBytes, NULL); #endif if (!result) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ResetPipe"); #endif return false; } return true; } // ResetPipe: // bool TUSBDevice::AbortPipe(int pipenum) { BOOL result = false; unsigned long nBytes; DWORD iBuf = pipenum; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::AbortPipe(pipenum=%d) \n",pipenum); #endif #ifdef CF__LINUX puts("not yet!!! AbortPipe "); #else result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_ABORTPIPE, &iBuf, sizeof(iBuf), NULL, 0, &nBytes, NULL); #endif if (!result) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::AbortPipe"); #endif return false; } return true; } // CyclePort: simulates unplug and re-plug of the device // bool TUSBDevice::CyclePort() { BOOL result = false; unsigned long nBytes; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::CyclePort() \n"); #endif #ifdef CF__LINUX puts("not yet!!! CyclePort "); #else result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_CYCLE_PORT, // IOCTL_SLBUSB_RESET, NULL, 0, NULL, 0, &nBytes, NULL); #endif if (!result) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::CyclePort"); #endif return false; } return true; } bool TUSBDevice::Reset() { BOOL result = false; unsigned long nBytes; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::Reset() \n"); #endif #ifdef CF__LINUX puts("not yet!!! Reset USB_RESET "); #else result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_RESET, NULL, 0, NULL, 0, &nBytes, NULL); #endif if (!result) { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ResetPort"); #endif return false; } return true; } // GetLastUSBError: // #ifdef CF__LINUX bool TUSBDevice::GetLastUSBError(unsigned long * error) #else bool TUSBDevice::GetLastUSBError(unsigned int * error) #endif { BOOL result = false; unsigned long nBytes; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::GetLastUSBError() \n"); #endif #ifdef CF__LINUX puts("not yet!! GetLastUSBError GET_LAST_ERROR "); #else result = DeviceIoControl (USBDeviceHandle, IOCTL_SLBUSB_GET_LAST_ERROR, NULL, 0, error, #ifdef CF__LINUX sizeof(unsigned long), #else sizeof(unsigned int), #endif &nBytes, NULL); #endif if (!result) { // #if (SHOW_BASIC_ERRORS) // ShowLastError("TUSBDevice::GetLastUSBError()"); // #endif return false; } return true; } void TUSBDevice::Hold8051() { VENDOR_REQUEST_IN myRequest; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::Hold8051() \n"); #endif myRequest.bRequest = VR_ANCHOR_DLD; // defines request handled by USB core myRequest.wValue = cpu_cs_reg; // 8051 control register myRequest.wIndex = 0; // not used myRequest.wLength = 1; // data length myRequest.bData = 1; // set reset bit; myRequest.direction = REQUEST_DIR_OUT; // PC -> USB device VendorRequest(&myRequest); } void TUSBDevice::Run8051() { VENDOR_REQUEST_IN myRequest; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::Run8051() \n"); #endif myRequest.bRequest = VR_ANCHOR_DLD; // defines request handled by USB core myRequest.wValue = cpu_cs_reg; // 8051 control register myRequest.wIndex = 0; // not used myRequest.wLength = 1; // data length myRequest.bData = 0; // clear reset bit; myRequest.direction = REQUEST_DIR_OUT; // PC -> USB device VendorRequest(&myRequest); } bool TUSBDevice::GetRevision(unsigned char *rev) { VENDOR_REQUEST_IN myRequest; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::GetRevision() \n"); #endif if (Desc->idVendor == EZUSB_VENDOR_ID) // request handled by USB core!!! myRequest.bRequest = VR_ANCHOR_DLD; else // handled by firmware!!! myRequest.bRequest = VR_GET_CHIP_REV; myRequest.wValue = cpu_cs_reg; // 8051 control register myRequest.wIndex = 0; // not used myRequest.wLength = 1; // data length myRequest.bData = 0; // readback data myRequest.direction = REQUEST_DIR_IN; // USB device -> PC status = VendorRequest(&myRequest); if (status) { *rev = (unsigned char)((myRequest.bData >> 4) & 0x0F); // shift cpucs register to get rev. field return true; } else return false; } #ifndef _BORLANDC bool TUSBDevice::LoadHexFileToEeprom(std::string FileName) { // ##4 struct HEX_RECORDS *Hex_Records=NULL; struct HEX_RECORDS *entry, *entry_prev=NULL, *current=NULL; FILE *image; int i,/*fd=0,*/status=0; //unsigned char data [1023]; //unsigned short data_addr = 0; size_t data_len = 0; //int rc; //int first_line = 1; int lines=0, bytes=0; // PINTEL_HEX_RECORD HexRecordStruct; unsigned char magicword; unsigned char VendorDeviceID[6]; unsigned char LastRecord[6]; unsigned short addoffset; // write magic word to enable EEPROM firmware load at power-up // 0xb2 load firmware from EEPROM EZ-USB // 0xc2 load firmware from EEPROM FX2LP if (is_fx) { addoffset = 8; magicword = 0xc2; } else { addoffset = 7; magicword = 0xb2; } if (SF_DEBUG_USB>0) printf("***> TUSBDevice::LoadHexFileToEeprom(file=%s) \n",FileName.c_str()); image = fopen (FileName.c_str(), "r"); for (;;) { char buf [512], *cp; char tmp, type; size_t len; unsigned idx, off; cp = fgets(buf, sizeof buf, image); if (cp == 0) { fprintf (stderr, "EOF without EOF record!\n"); status = -1; break; } lines++; if (buf[0] == '#') continue; if (buf[0] != ':') { fprintf (stderr, "not an ihex record: %s", buf); status = -2; break; } tmp = buf[3]; buf[3] = 0; len = strtoul(buf+1, 0, 16); buf[3] = tmp; tmp = buf[7]; buf[7] = 0; off = strtoul(buf+3, 0, 16); buf[7] = tmp; tmp = buf[9]; buf[9] = 0; type = (char)strtoul(buf+7, 0, 16); buf[9] = tmp; if (type == 1) { if (SF_DEBUG_USB>1) printf("***> Found EOF on hexfile\n"); break; } if (type != 0) { fprintf (stderr, "unsupported record type: %u\n", type); status = -3; break; } if ((len * 2) + 11 >= strlen(buf)) { fprintf (stderr, "record too short?\n"); status = -4; break; } if ((entry = (HEX_RECORDS*)calloc (1, sizeof *entry)) == 0) { status = -5; break; } entry->line_nr=lines; entry->HexRecord.Length=len; entry->HexRecord.Address=off; entry->HexRecord.Type=type; if (current) current->next=entry; if (!Hex_Records) Hex_Records=entry; current=entry; for (idx = 0, cp = buf+9 ; idx < len ; idx += 1, cp += 2) { tmp = cp[2]; cp[2] = 0; entry->HexRecord.Data[idx]=(unsigned char)strtoul(cp, 0, 16); cp[2] = tmp; bytes++; } data_len += len; } //-------- write to eeprom and free memory -------- for (entry = Hex_Records; entry; entry = entry->next) { if(SF_DEBUG_USB>0) { printf(" write line=%03d Len=%02d ADDR=%04X " ,entry->line_nr, entry->HexRecord.Length, entry->HexRecord.Address); for (i=0; iHexRecord.Length; i++) printf(" %02X",entry->HexRecord.Data[i]); printf("\n"); } if (status==0) { WriteDataRecordToEeprom(entry->HexRecord, addoffset); // write data to EEPROM addoffset += (unsigned short)(entry->HexRecord.Length + 4); } free(entry_prev); entry_prev=entry; } free(entry_prev); fclose(image); if (status==0) { WriteEEPROM(0, &magicword, 1); VendorDeviceID[0] = LSB(VendorId); VendorDeviceID[1] = MSB(VendorId); VendorDeviceID[2] = LSB(ProductId); VendorDeviceID[3] = MSB(ProductId); VendorDeviceID[4] = LSB(DeviceId); VendorDeviceID[5] = MSB(DeviceId); WriteEEPROM(1, VendorDeviceID, 6); if(is_fx) { unsigned char config = 0x01; // connected, 400 kHz I2C WriteEEPROM(7, &config, 1); } // write last data record LastRecord[0] = 0x80; LastRecord[1] = 0x01; LastRecord[2] = MSB(cpu_cs_reg); LastRecord[3] = LSB(cpu_cs_reg); LastRecord[4] = 0x00; WriteEEPROM(addoffset, LastRecord, 5); // write last data to EEPROM } if (status<0) return false; else return true; } //======================================================================================= #else bool TUSBDevice::LoadHexFileToEeprom(std::string FileName) { // #define MAX_HEX_SIZE (1024*8) // EEPROM data structure for firmware load: // // Address Contents //--------------------------------------------------------- // 0 0xB2 (0xC2), enables firmware download from EEPROM // 1 VID lb, Vendor ID // 2 VID hb // 3 PID lb, Product ID // 4 PID hb // 5 DID lb, Device ID // 6 DID hb // 7 config unsigned char (FX2LP only) // -------------------------------------------------------- // beginn of data records // -------------------------------------------------------- // 7 (8) Length hb, start of first data record // 8 (9) Length lb // 9 (10) Address hb // 10 (11) Address lb // 11 (12) first data unsigned char // . ... //--------------------------------------------------------- // more data records //--------------------------------------------------------- //--------------------------------------------------------- // last data record (MSB of Length must be 1) // write to CPUCS register to bring 8051 out of eset //--------------------------------------------------------- // 0x80 // 0x01 // 0x7F (0xE6) // 0x92 (0x00) // 0x00 TStringList *HexRecordStrings; std::string HexString; PINTEL_HEX_RECORD HexRecordStruct; unsigned char magicword; unsigned char VendorDeviceID[6]; unsigned char LastRecord[6]; unsigned short addoffset; // write magic word to enable EEPROM firmware load at power-up // 0xb2 load firmware from EEPROM EZ-USB // 0xc2 load firmware from EEPROM FX2LP if (is_fx) { addoffset = 8; magicword = 0xc2; } else { addoffset = 7; magicword = 0xb2; } HexRecordStrings = new TStringList(); /* if (!FileExists(FileName)) { MessageBox(NULL,"File not found.", "TUSBDevice::LoadHexFileToEeprom", MB_OK | MB_ICONEXCLAMATION); return false; } */ HexRecordStrings->LoadFromFile(AnsiString(FileName.c_str())); HexRecordStruct = (PINTEL_HEX_RECORD) malloc (sizeof(INTEL_HEX_RECORD) * HexRecordStrings->Count); for (int i = 0; i < HexRecordStrings->Count; i++) // read HEX records { HexString =std::string( HexRecordStrings->Strings[i].c_str()); if (HexString[0] != ':') { free (HexRecordStruct); delete (HexRecordStrings); MessageBox(NULL,"Wrong file format", "TUSBDevice::LoadHexFileToEeprom", MB_OK | MB_ICONEXCLAMATION); return false; } HexString = HexString.substr(1, HexString.length() - 1); // trim leading ":" HexRecordStruct[i].Length = (unsigned char) HexToInt2(HexString.substr(0,2)); // set length HexRecordStruct[i].Address = (unsigned short) HexToInt2(HexString.substr(2,4)); // set address HexRecordStruct[i].Type = (unsigned char) HexToInt2(HexString.substr(6,2)); // set type if ((HexRecordStruct[i].Type == 0x01) && (i != HexRecordStrings->Count -1)) // test EOF { MessageBox(NULL,"Unexpected end of file.", "TUSBDevice::LoadHexFileToEeprom", MB_OK | MB_ICONEXCLAMATION); free (HexRecordStruct); delete (HexRecordStrings); return false; } for (int j = 0; j < HexRecordStruct[i].Length; j++) HexRecordStruct[i].Data[j] = (unsigned char) HexToInt2(HexString.substr(8+(j*2),2)); // set data } for (int i = 0; i < HexRecordStrings->Count - 1 ; i++) // write HEX records (skipp EOF record) { WriteDataRecordToEeprom(HexRecordStruct[i], addoffset); // write data to EEPROM addoffset += (unsigned short)(HexRecordStruct[i].Length + 4); } WriteEEPROM(0, &magicword, 1); VendorDeviceID[0] = LSB(VendorId); VendorDeviceID[1] = MSB(VendorId); VendorDeviceID[2] = LSB(ProductId); VendorDeviceID[3] = MSB(ProductId); VendorDeviceID[4] = LSB(DeviceId); VendorDeviceID[5] = MSB(DeviceId); WriteEEPROM(1, VendorDeviceID, 6); if(is_fx) { unsigned char config = 0x01; // connected, 400 kHz I2C WriteEEPROM(7, &config, 1); } // write last data record LastRecord[0] = 0x80; LastRecord[1] = 0x01; LastRecord[2] = MSB(cpu_cs_reg); LastRecord[3] = LSB(cpu_cs_reg); LastRecord[4] = 0x00; WriteEEPROM(addoffset, LastRecord, 5); // write last data to EEPROM free (HexRecordStruct); delete (HexRecordStrings); return true; } #endif bool TUSBDevice::WriteDataRecordToEeprom(INTEL_HEX_RECORD HexRecordStruct, unsigned short Address) { unsigned char *buffer; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::WriteDataRecordToEeprom() \n"); if (SF_DEBUG_USB>5) { printf("***> Len=%02d ADDR=%04X ",HexRecordStruct.Length, HexRecordStruct.Address); for (int i=0; i= eeprom_user_data_offset) { MessageBox( NULL, "Error: EEPROM code space overlaps with user data!", "Error", MB_OK|MB_ICONINFORMATION ); free (buffer); return false; } WriteEEPROM(Address, buffer, (unsigned short)(HexRecordStruct.Length + 4)); free (buffer); return true; } bool TUSBDevice::InitXilinxConfPort() { unsigned char portreg; // configure port bits for xilinx configuration // // signal dir func // INIT read signals ready(1)/error(0) (old USB card only !!!) // RDWR write selects configuration write or readback (FX only) // BUSY read reads whether S3 chip is busy and not accepting new data (FX only) // PROG write clear config data, active low // DONE read device active, active high // CS1 write selects express config mode, active high // configure bits on portc to I/O mode if (!Read8051(xp_conf_port_cfg, &portreg, 1)) return false; // select port i/o func. for all lines if (is_fx) { portreg &= (unsigned char)~xp_rdwr; portreg &= (unsigned char)~xp_busy; } else { portreg &= ~xp_init; } portreg &= (unsigned char)~xp_prog; portreg &= (unsigned char)~xp_done; portreg &= (unsigned char)~xp_cs1; if (!Write8051(xp_conf_port_cfg, &portreg, 1)) return false; // select direction on portc lines if (!Read8051(xp_conf_port_oe, &portreg, 1)) return false; if (is_fx) { portreg |= (unsigned char) xp_rdwr; // write, OE = 1 portreg &= (unsigned char)~xp_busy; // read, OE = 0 } else { portreg &= (unsigned char)~xp_init; // read, OE = 0 } portreg |= (unsigned char) xp_prog; // write, OE = 1 portreg &= (unsigned char)~xp_done; // read, OE = 0 portreg |= (unsigned char) xp_cs1; // write, OE = 1 if (!Write8051(xp_conf_port_oe, &portreg, 1)) return false; return true; } bool TUSBDevice::SetXilinxConfPin(unsigned char pin, unsigned char data) { unsigned char portreg; if (!Read8051(xp_conf_port_rd, &portreg, 1)) return false; if ((data & 0x01) == 0) portreg &= (unsigned char)~pin; else portreg |= (unsigned char) pin; if(!Write8051(xp_conf_port_wr, &portreg, 1)) return false; return true; } bool TUSBDevice::GetXilinxConfPin(unsigned char pin) { unsigned char portreg; if (!Read8051(xp_conf_port_rd, &portreg, 1)) return false; return((portreg & pin) != 0); } bool TUSBDevice::WriteXilinxConfData(unsigned char *data, int size) { //unsigned char dummy[] = {0x00, 0x00, 0x00, 0x00}; unsigned char dummy[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; SwapBytes(data, size); if (!WriteXilinx(0, data, size)) return false; // WriteExternal(0x8000, dummy, 4); // four extra clock to enable start-up WriteXilinx(0, dummy, 8); // eight extra clock to enable start-up return true; } bool TUSBDevice::SetXilinxConfByte(unsigned char data) { if(!Write8051(xp_conf_port_wr, &data, 1)) return false; return true; } unsigned char TUSBDevice::GetXilinxConfByte(void) { unsigned char portreg; if (!Read8051(xp_conf_port_rd, &portreg, 1)) return 0; return(portreg); } bool TUSBDevice::XilinxAlreadyLoaded() { InitXilinxConfPort(); return GetXilinxConfPin(xp_done); } bool TUSBDevice::WriteXilinx(unsigned short address, unsigned char *Data, int length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::WriteXilinx(add=%d,data=%3d ..., len=%d) \n",address,Data[0],length); #endif sur.type = SUR_TYPE_XILINX; sur.dir = SUR_DIR_OUT; sur.addr = address; sur.length = (unsigned short) length; if (length <= 0xffff) status = SilabUsbRequest(&sur, Data); else status = SilabUsbRequest(&sur, Data, length); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::WriteXilinx"); #endif return false; } } bool TUSBDevice::ReadXilinx(unsigned short address, unsigned char *Data, int Length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>3) printf("***> TUSBDevice::ReadXilinx(len=%d) \n",Length); #endif sur.type = SUR_TYPE_XILINX; sur.dir = SUR_DIR_IN; sur.addr = address; sur.length = (unsigned short) Length; if (Length <= 0xffff) status = SilabUsbRequest(&sur, Data); else status = SilabUsbRequest(&sur, Data, Length); if (status) return true; else { #if (SHOW_BASIC_ERRORS) ShowLastError("TUSBDevice::ReadXilinx"); #endif return false; } } bool TUSBDevice::ConfigXilinx(unsigned char *Data, unsigned short length) { SILAB_USB_REQUEST sur; bool status; #ifdef CF__LINUX if (SF_DEBUG_USB>0) printf("***> TUSBDevice::ConfigXilinx(len=%d) \n",length); #endif sur.type = SUR_TYPE_XCONF; sur.dir = SUR_DIR_OUT; sur.addr = 0; sur.length = length; status = SilabUsbRequest(&sur, Data); if (status) return true; else { #if (SHOW_HIGHER_LEVEL_ERRORS) ShowLastError("TUSBDevice::ConfigXilinx"); #endif return false; } } bool TUSBDevice::SetPLLFrequency(double val) { if (this->ClkGen == NULL) return false; return ClkGen->SetFrequency(val); } bool TUSBDevice::SetPLLRefFrequency(double val) { if (this->ClkGen == NULL) return false; return ClkGen->SetRefClockFrequency(val); }