URL
https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk
Subversion Repositories or1k_soc_on_altera_embedded_dev_kit
[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [sw/] [adv_jtag_bridge/] [cable_sim.c] - Rev 12
Compare with Previous | Blame | View Log
/* cable_sim.c - Simulation connection drivers for the Advanced JTAG Bridge Copyright (C) 2001 Marko Mlinar, markom@opencores.org Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org This program 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. This program 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include "cable_common.h" #include "errcodes.h" #define debug(...) //fprintf(stderr, __VA_ARGS__ ) /* Only used in the vpi */ static int vpi_comm; static int vpi_port = 4567; static char *vpi_server = "localhost"; /* Only used for the rtl_sim */ static char *gdb_in = "gdb_in.dat"; static char *gdb_out = "gdb_out.dat"; /*-------------------------------------------[ rtl_sim specific functions ]---*/ int cable_rtl_sim_init() { FILE *fin = fopen (gdb_in, "wt+"); if(!fin) { fprintf(stderr, "Can not open %s\n", gdb_in); return APP_ERR_INIT_FAILED; } fclose(fin); return APP_ERR_NONE; } int cable_rtl_sim_out(uint8_t value) { FILE *fout; int num_read; int r; debug("O (%x)\n", value); fout = fopen(gdb_in, "wt+"); fprintf(fout, "F\n"); fflush(fout); fclose(fout); fout = fopen(gdb_out, "wt+"); fprintf(fout, "%02X\n", value); fflush(fout); fclose(fout); do { fout = fopen(gdb_out, "rt"); r = fscanf(fout,"%x", &num_read); fclose(fout); usleep(1000); debug(" (Ack %x) ", num_read); } while(!r || (num_read != (0x10 | value))); debug("\n"); return APP_ERR_NONE; } uint8_t cable_rtl_sim_inout(uint8_t value, uint8_t *inval) { FILE *fin = 0; char ch; uint8_t data; debug("IO ("); while(1) { fin = fopen(gdb_in, "rt"); if(!fin) { usleep(1000); continue; } ch = fgetc(fin); fclose(fin); if((ch != '0') && (ch != '1')) { usleep(1000); continue; } else break; } data = ch == '1' ? 1 : 0; debug("%x,", data); cable_rtl_sim_out(value); debug("%x)\n", value); *inval = data; return APP_ERR_NONE; } int cable_rtl_sim_opt(int c, char *str) { switch(c) { case 'd': if(!(gdb_in = malloc(strlen(str) + 12))) { /* 12 == strlen("gdb_in.dat") + 2 */ fprintf(stderr, "Unable to allocate enough memory\n"); return APP_ERR_MALLOC; } if(!(gdb_out = malloc(strlen(str) + 13))) { /* 13 == strlen("gdb_out.dat") + 2 */ fprintf(stderr, "Unable to allocate enough memory\n"); free(gdb_in); return APP_ERR_MALLOC; } sprintf(gdb_in, "%s/gdb_in.dat", str); sprintf(gdb_out, "%s/gdb_out.dat", str); break; default: fprintf(stderr, "Unknown parameter '%c'\n", c); return APP_ERR_BAD_PARAM; } return APP_ERR_NONE; } /*-----------------------------------------------[ VPI specific functions ]---*/ int cable_vpi_init() { struct sockaddr_in addr; struct hostent *he; if((vpi_comm = socket(PF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "Unable to create socket (%s)\n", strerror(errno)); return APP_ERR_CONNECT; } if((he = gethostbyname(vpi_server)) == NULL) { perror("gethostbyname"); return APP_ERR_CONNECT; } addr.sin_family = AF_INET; addr.sin_port = vpi_port; addr.sin_addr = *((struct in_addr *)he->h_addr); memset(addr.sin_zero, '\0', sizeof(addr.sin_zero)); if(connect(vpi_comm, (struct sockaddr *)&addr, sizeof(addr)) == -1) { fprintf(stderr, "Unable to connect to %s port %d (%s)\n", vpi_server, vpi_port, strerror(errno)); return APP_ERR_CONNECT; } debug("VPI connected!"); return APP_ERR_NONE; } int cable_vpi_out(uint8_t value) { uint8_t ack; int ret; /* Send the data to the socket */ ret = send(vpi_comm, &value, 1, 0); debug("Sent %d, ret %d\n", value, ret); do { /* Ok, read the data */ ret = recv(vpi_comm, &ack, 1, 0); if(ret < 0) { printf("Error during receive (%s)\n", strerror(errno)); return APP_ERR_CONNECT; } } while(ack != (value | 0x10)); return APP_ERR_NONE; } int cable_vpi_inout(uint8_t value, uint8_t *inval) { uint8_t dat; /* ask vpi to send us the out-bit */ dat = 0x80; send(vpi_comm, &dat, 1, 0); /* Wait and read the data */ recv(vpi_comm, &dat, 1, 0); if(dat > 1) fprintf(stderr, "Unexpected value: %i\n", dat); cable_vpi_out(value); *inval = dat; return APP_ERR_NONE; } void cable_vpi_wait() { uint8_t dat = 0x81; /* Get the sim to reply when the timeout has been reached */ if(send(vpi_comm, &dat, 1, 0) < 1) { fprintf(stderr, "Failed to send pkt in cable_vpi_wait(): %s\n", strerror(errno)); } /* block, waiting for the data */ if(recv(vpi_comm, &dat, 1, 0) < 1) { fprintf(stderr, "Recv failed in cable_vpi_wait(): %s\n", strerror(errno)); } if(dat != 0xFF) fprintf(stderr, "Warning: got wrong byte waiting for timeout: 0x%X\n", dat); } int cable_vpi_opt(int c, char *str) { switch(c) { case 'p': if((vpi_port = atoi(str)) == 0) { fprintf(stderr, "Bad port value for VPI sim: %s\n", str); return APP_ERR_BAD_PARAM; } break; case 's': vpi_server = strdup(str); if(vpi_server == NULL) { fprintf(stderr, "Unable to allocate enough memory for server string\n"); return APP_ERR_MALLOC; } break; default: fprintf(stderr, "Unknown parameter '%c'\n", c); return APP_ERR_BAD_PARAM; } return APP_ERR_NONE; }