bool FirewirePort::WriteQuadlet(unsigned char boardId, nodeaddr_t addr, quadlet_t data)
{
    int node = GetNodeId(boardId);
    if (node < MAX_NODES)
        return !raw1394_write(handle, baseNodeId+node, addr, 4, &data);
    else
        return false;
}
bool FirewirePort::WriteBlock(unsigned char boardId, nodeaddr_t addr, quadlet_t *data,
                              unsigned int nbytes)
{
    int node = GetNodeId(boardId);
    if (node < MAX_NODES)
        return !raw1394_write(handle, baseNodeId+node, addr, nbytes, data);
    else
        return false;
}
Пример #3
0
int write_data(raw1394handle_t h, nodeid_t node, nodeaddr_t address, size_t length, quadlet_t *buf)
{
  int ret;
  while((ret = raw1394_write(h ,node, address, length, buf)) && errno == EAGAIN)
    usleep(100000); // wait 100ms, device is not ready, since this is part of the initialisation it is no problem (from a real-time perspective) to retry

  if(ret)
    fprintf(stderr, "Failed to write data: (%d) %s\n", errno, strerror(errno));
  return ret;
}
Пример #4
0
int write_data_char(raw1394handle_t h, nodeid_t node, nodeaddr_t address, unsigned char buf)
{
  int ret;
  while((ret = raw1394_write(h, node, address, 1, (quadlet_t *) &buf)) && errno == EAGAIN)
  {
    printf("waiting to write data\n");
    usleep(100000); // wait 100ms, device is not ready, since this is part of the initialisation it is no problem (from a real-time perspective) to retry
  }

  if(ret)
    fprintf(stderr, "Failed to write char: (%d) %s\n", errno, strerror(errno));
  return ret;
}
Пример #5
0
int cooked1394_write(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
                     size_t length, quadlet_t *data)
{
	int retval, i;
	struct timespec ts = {0, RETRY_DELAY};
	for(i=0; i<MAXTRIES; i++) {
		retval = raw1394_write(handle, node, addr, length, data);
		if (retval < 0 && errno == EAGAIN)
			nanosleep(&ts, NULL);
		else
			return retval;
	}
	return -1;
}
void FirewirePort::StopCycleStartPacket(void)
{
    // IMPORTANT: Disable Cycle Start Packet, no isochronous
    int rc = 0;  // return code
    quadlet_t data_stop_cmc = bswap_32(0x100);
    rc = raw1394_write(handle,
                       raw1394_get_local_id(handle),
                       CSR_REGISTER_BASE + CSR_STATE_CLEAR,
                       4,
                       &data_stop_cmc);
    if (rc) {
        outStr << "*****Error: can NOT disable cycle start packet" << std::endl;
    } else {
        outStr << "FirewirePort: successfully disabled cycle start packet" << std::endl;
    }
}
Пример #7
0
/** Try again upto MAX_RETRIES if raw1394_write returns EGAIN. */
int
raw1394_write_retry(raw1394handle_t handle, nodeid_t node, nodeaddr_t addr,
		   size_t length, quadlet_t *buffer)
{
  int retries = MAX_RETRIES;
  int ret;

 again:
  ret = raw1394_write(handle, node, addr, length, buffer);
  if (ret != 0) {
    if ((errno == EAGAIN) && (retries-- > 0))
      /* Seems to be a bug */
      goto again;
  }

  return ret;
}
bool FirewirePort::WriteAllBoardsBroadcast(void)
{
    // check hanle
    if (!handle) {
        outStr << "WriteAllBoardsBroadcast: handle for port " << PortNum << " is NULL" << std::endl;
        return false;
    }

    // sanity check vars
    bool allOK = true;
    bool noneWritten = true;

    // loop 1: broadcast write block

    // construct broadcast write buffer
    const int numOfChannel = 4;
    quadlet_t bcBuffer[numOfChannel * MAX_NODES];
    memset(bcBuffer, 0, sizeof(bcBuffer));
    int bcBufferOffset = 0; // the offset for new data to be stored in bcBuffer (bytes)
    int numOfBoards = 0;

    for (int board = 0; board < max_board; board++) {
        if (BoardList[board]) {
            numOfBoards++;
            quadlet_t *buf = BoardList[board]->GetWriteBuffer();
            unsigned int numBytes = BoardList[board]->GetWriteNumBytes();
            memcpy(bcBuffer + bcBufferOffset/4, buf, numBytes-4); // -4 for ctrl offset
            // bcBufferOffset equals total numBytes to write, when the loop ends
            bcBufferOffset = bcBufferOffset + numBytes - 4;
        }
    }

    // now broadcast out the huge packet
    bool ret = true;

#if FAKEBC
    ret = !raw1394_write(handle,
                         baseNodeId,
                         0xffffffff0000,
                         bcBufferOffset,
                         bcBuffer);
#else
    ret = WriteBlockBroadcast(0xffffff000000,  // now the address is hardcoded
                              bcBuffer,
                              bcBufferOffset);
#endif

    // loop 2: send out control quadlet if necessary
    for (int board = 0; board < max_board; board++) {
        if (BoardList[board]) {
            quadlet_t *buf = BoardList[board]->GetWriteBuffer();
            unsigned int numBytes = BoardList[board]->GetWriteNumBytes();
            unsigned int numQuads = numBytes/4;
            quadlet_t ctrl = buf[numQuads-1];  // Get last quedlet
            bool ret2 = true;
            if (ctrl) {  // if anything non-zero, write it
                ret2 = WriteQuadlet(board, 0x00, ctrl);
                if (ret2) noneWritten = false;
                else allOK = false;
            }
            // SetWriteValid clears the buffer if the write was valid
            BoardList[board]->SetWriteValid(ret&&ret2);
        }
    }

    // pullEvents
    if (noneWritten) {
        PollEvents();
    }

    // return
    return allOK;
}
bool FirewirePort::ReadAllBoardsBroadcast(void)
{
    if (!handle || !handle_bc) {
        outStr << "ReadAllBoardsBroadcast: handle for port " << PortNum << " is NULL" << std::endl;
        return false;
    }

    bool ret;
    bool allOK = true;
    bool noneRead = true;
    int hub_node_id = GetNodeId(HubBoard_->BoardId);   //  ZC: NOT USE PLACEHOLDER

    //--- send out broadcast read request -----

#if 0
    quadlet_t debugData;
    nodeaddr_t debugAddr = 0x03;

    bool retdebug = !raw1394_read(handle,
                                  baseNodeId + hub_node_id,    // boardid 7
                                  debugAddr,           // read from hub addr
                                  4,          // read all 16 boards
                                  &debugData);
    if (!retdebug) {
        raw1394_errcode_t ecode = raw1394_get_errcode(handle);
        std::cerr << "debug read ecode = " << ecode << " to_errno = " << raw1394_errcode_to_errno(ecode) << "  "
                  << strerror(raw1394_errcode_to_errno(ecode)) << std::endl;
    }
#endif

    // sequence number from 16 bits 0 to 65535
    ReadSequence_++;
    if (ReadSequence_ == 65536) {
        ReadSequence_ = 1;
    }
    quadlet_t bcReqData = bswap_32((ReadSequence_ << 16) + BoardExistMask_);
    nodeaddr_t bcReqAddr = 0xffffffff000F;    // special address to trigger broadcast read

#if FAKEBC
    ret = !raw1394_write(handle,
                              baseNodeId,
                              bcReqAddr,
                              4,
                              &bcReqData);
    if (!ret) {
        raw1394_errcode_t ecode = raw1394_get_errcode(handle);
        std::cerr << "bbbbbbb fake ecode = " << ecode << " to_errno = " << raw1394_errcode_to_errno(ecode) << "  "
                  << strerror(raw1394_errcode_to_errno(ecode)) << std::endl;
    }
#else
    WriteQuadletBroadcast(bcReqAddr, bcReqData);
#endif

//    // Manual sleep 50 us
    timeval start, check;
    gettimeofday(&start, NULL);
    while(true) {
        gettimeofday(&check, NULL);
        if (((check.tv_sec-start.tv_sec)*1000000 + check.tv_usec-start.tv_usec) > (5.0*NumOfNodes_+10.0)) {
            break;
        }
    }

    // initialize max buffer
    const int hubReadSize = 272;     // 16 * 17 = 272 max
    quadlet_t hubReadBuffer[hubReadSize];
    memset(hubReadBuffer, 0, sizeof(hubReadBuffer));

    // raw1394_read 0 = SUCCESS, -1 = FAIL, flip return value
    ret = !raw1394_read(handle,
                        baseNodeId + hub_node_id,
                        0x1000,           // read from hub addr
                        272 * 4,          // read all 16 boards
                        hubReadBuffer);


    // ----- DEBUG -----------
    static int raw1394readCounter = 0;
    if (!ret) {
        raw1394readCounter++;
        raw1394_errcode_t ecode = raw1394_get_errcode(handle);
        std::cerr << "ecode = " << ecode << " to_errno = " << raw1394_errcode_to_errno(ecode) << "  "
                  << strerror(raw1394_errcode_to_errno(ecode)) << std::endl;
        std::cerr << "raw1394_read failed " << raw1394readCounter << ": " << strerror(errno) << std::endl;
    }
    // -----------------------

    for (int board = 0; board < max_board; board++) {
        if (BoardList[board]) {
            const int readSize = 17;  // 1 seq + 16 data, unit quadlet
            quadlet_t readBuffer[readSize];

            memcpy(readBuffer, &(hubReadBuffer[readSize * board + 0]), readSize * 4);

            unsigned int seq = (bswap_32(readBuffer[0]) >> 16);

            static int errorcounter = 0;
            if (ReadSequence_ != seq) {
                errorcounter++;
                outStr << "errorcounter = " << errorcounter << std::endl;
                outStr << std::hex << seq << "  " << ReadSequence_ << "  " << (int)board << std::endl;
            }

            memcpy(BoardList[board]->GetReadBuffer(), &(readBuffer[1]), (readSize-1) * 4);

            if (ret) noneRead = false;
            else allOK = false;
            BoardList[board]->SetReadValid(ret);
        }
    }

    if (noneRead) {
        PollEvents();
    }

    return allOK;
}
Пример #10
0
int
main(int argc, char **argv)
{
  /* Command line parsing */
  int opt;
  unsigned port = 0;
  unsigned step = 128;

  enum { INVALID, PEEK, POKE, SCREEN } mode = INVALID;

  const char *name = strippath(argv[0]);
  if (strcmp(name, "fw_peek") == 0) {
    mode = PEEK;
  } else if (strcmp(name, "fw_poke") == 0) {
    mode = POKE;
#ifndef NO_FW_SCREEN
  } else if (strcmp(name, "fw_screen") == 0) {
    mode = SCREEN;
#endif
  }

  if (mode == INVALID) {
    fprintf(stderr, "Could not decide, whether we are fw_peek or fw_poke.\n");
    return EXIT_FAILURE;
  }

  while ((opt = getopt(argc, argv, "p:b:")) != -1) {
    switch (opt) {
    case 'p':
      port = strtoul(optarg, 0, 0);
      break;
    case 'b':
      step = strtoul(optarg, 0, 0);
      break;
    default:
      goto print_usage;
    }
  }

  if (((mode == PEEK) && (argc - optind) != 3) ||
      ((mode == POKE) && (argc - optind) != 2) ||
      ((mode == SCREEN) && (argc - optind) != 5)) {
  print_usage:
    fprintf(stderr, (mode == PEEK) ? usage_peek : 
                    (mode == POKE) ? usage_poke : usage_screen, name);
    return EXIT_FAILURE;
  }

  uint64_t guid    = strtoull(argv[optind],     NULL, 0);
  uint64_t address = strtoull(argv[optind + 1], NULL, 0);
  uint64_t length;
  uint32_t width, height, depth;
  if (mode == PEEK) length = strtoull(argv[optind + 2], NULL, 0);
  if (mode == SCREEN) {
    width  = strtoul(argv[optind + 2], NULL, 0);
    height = strtoul(argv[optind + 3], NULL, 0);
    depth  = strtoul(argv[optind + 4], NULL, 0);
    length = 1ULL * depth / 8 * width * height;
  }

  raw1394handle_t fw_handle = raw1394_new_handle_on_port(port);

  if (fw_handle == NULL) {
    perror("raw1394_new_handle_on_port");
    return EXIT_FAILURE;
  }

  nodeid_t target;

  // 63 is broadcast. Ignore that.
  if (guid < 63) {
    // GUID is actually a node number.
    target = LOCAL_BUS | (nodeid_t)guid;
  } else {
    for (unsigned no = 0; no < 63; no++) {
      nodeid_t test_node = LOCAL_BUS | (nodeid_t)no;
      uint32_t guid_hi;
      uint32_t guid_lo;

      int res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 4*4,
			     4, &guid_lo);
      if (res != 0) { perror("read guid_lo"); return -1; }
      res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 3*4,
			 4, &guid_hi);
      if (res != 0) { perror("read guid_hi"); return -1; }

      uint64_t test_guid = (uint64_t)ntohl(guid_hi) << 32 | ntohl(guid_lo);
      if (test_guid == guid) { 
	target = test_node;
	goto target_found;
      }
    }
    return -1;
  target_found:
    ;
  }

  quadlet_t buf[step/sizeof(quadlet_t)];

  switch (mode) {
  case SCREEN:
#ifndef NO_FW_SCREEN
    {
      if (SDL_Init(SDL_INIT_VIDEO) < 0) { perror("init sdl"); return -1; }

      SDL_Surface *screen = SDL_SetVideoMode(width, height, depth, SDL_SWSURFACE);

      if (!screen) { perror("sdl video mode"); return -1; }

      while (true) {

        quadlet_t * buf = reinterpret_cast<quadlet_t *>(screen->pixels);
        for (uint64_t cur = address; cur < address+length; cur += step, buf += step/sizeof(quadlet_t)) {
          size_t size = (cur + step > address+length) ? (address+length - cur) : step;
          int res = raw1394_read(fw_handle, target, cur, size, buf);
          if (res != 0) { perror("read data"); return EXIT_FAILURE; }
        }

        SDL_UpdateRect(screen, 0, 0, width, height);
        SDL_Delay(500);

        SDL_Event event;
        if (SDL_PollEvent(&event))
	  if (event.type == SDL_QUIT) exit(1);
      }
    }
    break;
#else
    abort();
#endif	// NO_FW_SCREEN
  case PEEK:
    for (uint64_t cur = address; cur < address+length; cur += step) {
      size_t size = (cur + step > address+length) ? (address+length - cur) : step;
      int tries = 5;
again:
      int res = raw1394_read(fw_handle, target, cur, size, buf);
      if (res != 0) { if (tries-- > 0) goto again; perror("read data"); return EXIT_FAILURE; }
      if (write(STDOUT_FILENO, buf, size) < 0) {
	perror("write");
	return EXIT_FAILURE;
      }
    }
    break;
  case POKE:
    for (uint64_t cur = address;;cur += step) {
      ssize_t size = read(STDIN_FILENO, buf, step);
      if (size == 0)
	break;
      if (size < 0) {
	perror("read");
	return EXIT_FAILURE;
      }

      int res = raw1394_write(fw_handle, target, cur, size, buf);
      if (res != 0) { perror("write data"); return EXIT_FAILURE; }

      if (size < step)
	break;
    }
  }

  return 0;
}
Пример #11
0
int
main(int argc, char **argv)
{
  /* Command line parsing */
  int opt;
  unsigned port = 0;
  unsigned step = 128;

  enum { INVALID, PEEK, POKE } mode = INVALID;

  const char *name = strippath(argv[0]);
  if (strcmp(name, "fw_peek") == 0) {
    mode = PEEK;
  } else if (strcmp(name, "fw_poke") == 0) {
    mode = POKE;
  }

  if (mode == INVALID) {
    fprintf(stderr, "Could not decide, whether we are fw_peek or fw_poke.\n");
    return EXIT_FAILURE;
  }

  while ((opt = getopt(argc, argv, "p:b:")) != -1) {
    switch (opt) {
    case 'p':
      port = strtoul(optarg, 0, 0);
      break;
    case 'b':
      step = strtoul(optarg, 0, 0);
      break;
    default:
      goto print_usage;
    }
  }

  if (((mode == PEEK) && (argc - optind) != 3) ||
      ((mode == POKE) && (argc - optind) != 2)) {
  print_usage:
    fprintf(stderr, (mode == PEEK) ? usage_peek : usage_poke, name);
    return EXIT_FAILURE;
  }

  uint64_t guid    = strtoull(argv[optind],     NULL, 0);
  uint64_t address = strtoull(argv[optind + 1], NULL, 0);
  uint64_t length;
  if (mode == PEEK) length = strtoull(argv[optind + 2], NULL, 0);

  raw1394handle_t fw_handle = raw1394_new_handle_on_port(port);

  if (fw_handle == NULL) {
    perror("raw1394_new_handle_on_port");
    return EXIT_FAILURE;
  }

  nodeid_t target;

  // 63 is broadcast. Ignore that.
  if (guid < 63) {
    // GUID is actually a node number.
    target = LOCAL_BUS | (nodeid_t)guid;
  } else {
    for (unsigned no = 0; no < 63; no++) {
      nodeid_t test_node = LOCAL_BUS | (nodeid_t)no;
      uint32_t guid_hi;
      uint32_t guid_lo;

      int res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 4*4,
			     4, &guid_lo);
      if (res != 0) { perror("read guid_lo"); return -1; }
      res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 3*4,
			 4, &guid_hi);
      if (res != 0) { perror("read guid_hi"); return -1; }

      uint64_t test_guid = (uint64_t)ntohl(guid_hi) << 32 | ntohl(guid_lo);
      if (test_guid == guid) { 
	target = test_node;
	goto target_found;
      }
    }
    return -1;
  target_found:
    ;
  }

  quadlet_t buf[step/sizeof(quadlet_t)];

  switch (mode) {
  case PEEK:
    for (uint64_t cur = address; cur < address+length; cur += step) {
      size_t size = (cur + step > address+length) ? (address+length - cur) : step;
      int tries = 5;
again:
      int res = raw1394_read(fw_handle, target, cur, size, buf);
      if (res != 0) { if (tries-- > 0) goto again; perror("read data"); return EXIT_FAILURE; }
      if (write(STDOUT_FILENO, buf, size) < 0) {
	perror("write");
	return EXIT_FAILURE;
      }
    }
    break;
  case POKE:
    for (uint64_t cur = address;;cur += step) {
      ssize_t size = read(STDIN_FILENO, buf, step);
      if (size == 0)
	break;
      if (size < 0) {
	perror("read");
	return EXIT_FAILURE;
      }

      int res = raw1394_write(fw_handle, target, cur, size, buf);
      if (res != 0) { perror("write data"); return EXIT_FAILURE; }

      if (size < step)
	break;
    }
  }

  return 0;
}