/*----------------------------------------------------------------------------------------------*/ /*! \file gn3s.cpp // // FILENAME: gn3s.cpp // // DESCRIPTION: Impelements the GN3S class. // // DEVELOPERS: Gregory W. Heckler (2003-2009) // // LICENSE TERMS: Copyright (c) Gregory W. Heckler 2009 // // This file is part of the GPS Software Defined Radio (GPS-SDR) // // The GPS-SDR is free software; you can redistribute it and/or modify it under the terms of the // GNU General Public License as published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. The GPS-SDR is distributed in the hope that // it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // // Note: Comments within this file follow a syntax that is compatible with // DOXYGEN and are utilized for automated document extraction // // Reference: */ /*----------------------------------------------------------------------------------------------*/ #include "gn3s.h" #include #include #include #include #include "fusb_linux.h" static char debug = 1; //!< 1 = Verbose /*----------------------------------------------------------------------------------------------*/ gn3s::gn3s(int _which) { //int fsize; bool ret; which = _which; fx2_device = NULL; fx2_handle = NULL; gn3s_vid = GN3S_VID; gn3s_pid = GN3S_PID; /* Get the firmware embedded in the executable */ //fstart = (int) &_binary_usrp_gn3s_firmware_ihx_start; //fsize = strlen(_binary_usrp_gn3s_firmware_ihx_start); //gn3s_firmware = new char[fsize + 10]; //memcpy(&gn3s_firmware[0], (void *)fstart, fsize); // Load the firmware from external file (Javier) //gn3s_firmware[fsize] = NULL; /* Search all USB busses for the device specified by VID/PID */ fx2_device = usb_fx2_find(gn3s_vid, gn3s_pid, debug, 0); if (!fx2_device) { /* Program the board */ ret = prog_gn3s_board(); if(ret) { fprintf(stdout, "Could not flash GN3S device\n"); throw(1); } /* Need to wait to catch change */ sleep(2); /* Search all USB busses for the device specified by VID/PID */ fx2_device = usb_fx2_find(gn3s_vid, gn3s_pid, debug, 0); } else { fprintf(stdout, "Found GN3S Device\n"); } /* Open and configure FX2 device if found... */ ret = usb_fx2_configure(fx2_device, &fx2_config); if(ret) { fprintf(stdout, "Could not obtain a handle to the GN3S device\n"); throw(1); } } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ gn3s::~gn3s() { usrp_xfer(VRQ_XFER, 0); //delete gn3s_firmware; delete fx2_config.d_ephandle; delete fx2_config.d_devhandle; usb_release_interface(fx2_config.udev, fx2_config.interface); usb_close(fx2_config.udev); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ int gn3s::prog_gn3s_board() { char a; struct usb_bus *bus; struct usb_device *dev; //struct usb_dev_handle *han; int vid, pid; dev = NULL; usb_init(); usb_find_busses(); usb_find_devices(); vid = (VID_OLD); pid = (PID_OLD); for(bus = usb_busses; bus; bus = bus->next) { for(dev = bus->devices; dev; dev = dev->next) { if((dev->descriptor.idVendor == vid) && (dev->descriptor.idProduct == pid)) { fx2_device = dev; fprintf(stdout,"GN3S Device Found... awaiting firmware flash \n"); break; } } } if(fx2_device == NULL) { fprintf(stderr,"Cannot find vid 0x%x pid 0x%x \n", vid, pid); return -1; } printf("Using device vendor id 0x%04x product id 0x%04x\n", fx2_device->descriptor.idVendor, fx2_device->descriptor.idProduct); fx2_handle = usb_open(fx2_device); /* Do the first set 0xE600 1 */ char c[] = "1"; char d[] = "0"; a = atoz(c); fprintf(stdout,"GN3S flashing ... \n"); upload_ram(&a, (PROG_SET_CMD),1); program_fx2(NULL, 1); a = atoz(d); upload_ram(&a, (PROG_SET_CMD),1); fprintf(stdout,"GN3S flash complete! \n"); usb_close(fx2_handle); return(0); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ int gn3s::atoz(char *s) { int a; if(!strncasecmp("0x", s, 2)){ sscanf(s, "%x", &a); return a; } return atoi(s); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ void gn3s::upload_ram(char *buf, int start, int len) { int i; int tlen; int quanta = 16; int a; for (i = start; i < start + len; i += quanta) { tlen = len + start - i; if (tlen > quanta) tlen = quanta; if (debug >= 3) printf("i = %d, tlen = %d \n", i, tlen); a = usb_control_msg(fx2_handle, 0x40, 0xa0, i, 0, buf + (i - start), tlen, 1000); if (a < 0) { fprintf(stderr, "Request to upload ram contents failed: %s\n", usb_strerror()); return; } } } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ void gn3s::program_fx2(char *filename, char mem) { FILE *f; char s[1024]; char data[256]; char checksum, a; int length, addr, type, i; unsigned int b; // *** mod javier: load firmware from external file *** //f = tmpfile(); /* Dump firmware into temp file */ //fputs(gn3s_firmware, f); //rewind(f); f = fopen ("gn3s_firmware.ihx","r"); if (f!=NULL) { printf("GN3S firmware file found!\n"); }else{ printf("Could not open GN3S firmware file!\n"); return; } while (!feof(f)) { fgets(s, 1024, f); /* we should not use more than 263 bytes normally */ if (s[0] != ':') { fprintf(stderr, "%s: invalid string: \"%s\"\n", filename, s); continue; } sscanf(s + 1, "%02x", &length); sscanf(s + 3, "%04x", &addr); sscanf(s + 7, "%02x", &type); if (type == 0) { // printf("Programming %3d byte%s starting at 0x%04x", // length, length==1?" ":"s", addr); a = length + (addr & 0xff) + (addr >> 8) + type; for (i = 0; i < length; i++) { sscanf(s + 9 + i * 2, "%02x", &b); data[i] = b; a = a + data[i]; } sscanf(s + 9 + length * 2, "%02x", &b); checksum = b; if (((a + checksum) & 0xff) != 0x00) { printf(" ** Checksum failed: got 0x%02x versus 0x%02x\n", (-a) & 0xff, checksum); continue; } else { //printf(", checksum ok\n"); } upload_ram(data, addr, length); } else { if (type == 0x01) { printf("End of file\n"); fclose(f); return; } else { if (type == 0x02) { printf("Extended address: whatever I do with it ?\n"); continue; } } } } fclose(f); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ struct usb_device* gn3s::usb_fx2_find(int vid, int pid, char info, int ignore) { struct usb_bus *bus; struct usb_device *dev; struct usb_device *fx2 = NULL; usb_dev_handle *udev; int count = 0; int ret; char str[256]; usb_init(); usb_find_busses(); usb_find_devices(); for(bus = usb_busses; bus; bus = bus->next) { for(dev = bus->devices; dev; dev = dev->next) { if((dev->descriptor.idVendor == vid) && (dev->descriptor.idProduct == pid)) { fx2 = dev; } if(fx2 != NULL && info) { udev = usb_open(fx2); if(udev && dev->descriptor.idVendor == vid && dev->descriptor.idProduct == pid && count < ignore) { if(fx2->descriptor.iManufacturer) { ret = usb_get_string_simple(udev, fx2->descriptor.iManufacturer, str, sizeof(str)); if(ret > 0) printf("- Manufacturer : %s\n", str); else printf("- Unable to fetch manufacturer string\n"); } if(fx2->descriptor.iProduct) { ret = usb_get_string_simple(udev, fx2->descriptor.iProduct, str, sizeof(str)); if(ret > 0) printf("- Product : %s\n", str); else printf("- Unable to fetch product string\n"); } if(fx2->descriptor.iSerialNumber) { ret = usb_get_string_simple(udev, fx2->descriptor.iSerialNumber, str, sizeof(str)); if(ret > 0) printf("- Serial Number: %s\n", str); else printf("- Unable to fetch serial number string\n"); } usb_close (udev); return fx2; } else if(udev && dev->descriptor.idVendor == vid && dev->descriptor.idProduct == pid && count >= ignore) { count++; } if(!fx2->config) { printf(" Could not retrieve descriptors\n"); continue; } for(int i = 0; i < fx2->descriptor.bNumConfigurations; i++) { //print_configuration(&fx2->config[i]); } } } } return fx2; } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ bool gn3s::usb_fx2_configure(struct usb_device *fx2, fx2Config *fx2c) { char status = 0; int interface = RX_INTERFACE; int altinterface = RX_ALTINTERFACE; usb_dev_handle *udev; fusb_ephandle *d_ephandle; fusb_devhandle *d_devhandle; udev = usb_open(fx2); if(!udev) { fprintf(stdout, "Could not obtain a handle to GNSS Front-End device \n"); return -1; } else { if(debug) printf("Received handle for GNSS Front-End device \n"); if(usb_set_configuration (udev, 1) < 0) { fprintf (stdout, "error in %s, \n%s \n", __FUNCTION__, usb_strerror()); usb_close (udev); status = -1; } if(usb_claim_interface (udev, interface) < 0) { fprintf (stdout, "error in %s, \n%s \n", __FUNCTION__, usb_strerror()); usb_close (udev); fprintf (stdout, "\nDevice not programmed? \n"); usb_close (udev); status = -1; throw(0); } if(usb_set_altinterface (udev, altinterface) < 0) { fprintf (stdout, "error in %s, \n%s \n", __FUNCTION__, usb_strerror()); usb_close (udev); usb_release_interface (udev, interface); usb_close (udev); status = -1; } d_devhandle = make_devhandle(udev); d_ephandle = d_devhandle->make_ephandle(RX_ENDPOINT, true, FUSB_BLOCK_SIZE, FUSB_NBLOCKS); if(!d_ephandle->start()) { fprintf (stdout, "usrp0_rx: failed to start end point streaming"); usb_strerror (); status = -1; } if(status == 0) { fx2c->interface = interface; fx2c->altinterface = altinterface; fx2c->udev = udev; fx2c->d_devhandle = d_devhandle; fx2c->d_ephandle = d_ephandle; return 0; } else { return -1; } } } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ fusb_devhandle* gn3s::make_devhandle(usb_dev_handle *udh) { return new fusb_devhandle_linux(udh); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ int gn3s::read(void *buff, int bytes) { return(fx2_config.d_ephandle->read(buff, bytes)); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ bool gn3s::check_rx_overrun() { bool overrun; _get_status(GS_RX_OVERRUN, &overrun); return(overrun); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ bool gn3s::_get_status(int command, bool *trouble) { unsigned char status; if(write_cmd(VRQ_GET_STATUS, 0, command, &status, sizeof(status)) != sizeof (status)) return false; *trouble = status; return true; } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ bool gn3s::usrp_xfer(char VRQ_TYPE, bool start) { int r; r = write_cmd(VRQ_TYPE, start, 0, 0, 0); return(r == 0); } /*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/ int gn3s::write_cmd(int request, int value, int index, unsigned char *bytes, int len) { int requesttype; int r; requesttype = (request & 0x80) ? VRT_VENDOR_IN : VRT_VENDOR_OUT; r = usb_control_msg (fx2_config.udev, requesttype, request, value, index, (char *) bytes, len, 1000); if(r < 0) { /* We get EPIPE if the firmware stalls the endpoint. */ if(errno != EPIPE) fprintf (stdout, "usb_control_msg failed: %s\n", usb_strerror()); } return r; } /*----------------------------------------------------------------------------------------------*/