Ejemplo n.º 1
0
		/// Handle completion of a read operation. 
		void handleRead(const boost::system::error_code& error, std::size_t bytes_transferred)
		{

			if (!error){
				readBytes += bytes_transferred;
				readBuff.has_written(bytes_transferred);
				onReadMsg(readBuff, writeBuff);
				readBuff.discard_all();

				reading = false;

				if (writeBuff.readable_bytes()>0){
					//std::cout << "going to send " << writeBuff.readable_bytes() << std::endl;
					//std::cout << writeBuff.as_string() << std::endl;
					LOG_DEBUG << "going to send " << writeBuff.readable_bytes();
					{

						size_t out_put_size = 256;
						if (out_put_size > writeBuff.readable_bytes()){
							out_put_size = writeBuff.readable_bytes();
						}
						
						LOG_DEBUG << writeBuff.as_string(0,out_put_size);
					}
					startWrite();
				}
				else{
					startRead();
				}

			}
			else{
				if (error == boost::asio::error::misc_errors::eof){
					LOG_INFO << " Client disconnectd:" << remoteAddr.address() << "  " << remoteAddr.port();
				}
				else{
					LOG_ERR << remoteAddr.address() << "  " << remoteAddr.port()
						<< ",error =" << error.value()
						<< ",msg=" << error.message();
				}
			}
			reading = false;
		}
Ejemplo n.º 2
0
//------------------------------------------------------------------------------
SdoDialog::SdoDialog()
{
    QVBoxLayout* mainLayout = new QVBoxLayout;

    /* create labels and buttons */
    QLabel*      label = new QLabel("Enter parameters for SDO transfer");
    QPushButton* closeButton = new QPushButton("&Close");
    this->readButton = new QPushButton("&Read");
    this->writeButton = new QPushButton("&Write");

    /* create edit fields */
    this->pNodeIdEdit = new QLineEdit("0");
    this->pNodeIdEdit->setToolTip("Target node-ID. Hexadecimal numbers shall be prefixed with 0x. Local node is addressed with node-ID 0");

    this->pObjectEdit = new QLineEdit("0x1006/0");
    this->pObjectEdit->setToolTip("Object index and sub-index separated by / or space. Hexadecimal numbers shall be prefixed with 0x.");

    this->pDataEdit = new QLineEdit("");

    this->pDataTypeBox = new QComboBox();
    this->pDataTypeBox->addItem("UNSIGNED8", QVariant::fromValue(kObdTypeUInt8));
    this->pDataTypeBox->addItem("UNSIGNED16", QVariant::fromValue(kObdTypeUInt16));
    this->pDataTypeBox->addItem("UNSIGNED32", QVariant::fromValue(kObdTypeUInt32));
    this->pDataTypeBox->addItem("UNSIGNED64", QVariant::fromValue(kObdTypeUInt64));
    this->pDataTypeBox->addItem("INTEGER8", QVariant::fromValue(kObdTypeInt8));
    this->pDataTypeBox->addItem("INTEGER16", QVariant::fromValue(kObdTypeInt16));
    this->pDataTypeBox->addItem("INTEGER32", QVariant::fromValue(kObdTypeInt32));
    this->pDataTypeBox->addItem("INTEGER64", QVariant::fromValue(kObdTypeInt64));
    this->pDataTypeBox->addItem("VSTRING", QVariant::fromValue(kObdTypeVString));
    this->pDataTypeBox->addItem("DOMAIN/OSTRING/Hex string", QVariant::fromValue(kObdTypeDomain));
    this->pDataTypeBox->setCurrentIndex(2);

    this->pSdoTypeBox = new QComboBox();
    this->pSdoTypeBox->addItem("ASnd", QVariant::fromValue(kSdoTypeAsnd));
    this->pSdoTypeBox->addItem("UDP", QVariant::fromValue(kSdoTypeUdp));

    this->pAbortCodeLabel = new QLabel("Not yet transferred.");

    /* create form */
    QFormLayout *formLayout = new QFormLayout;
    formLayout->addRow(tr("&Node-ID:"), this->pNodeIdEdit);
    formLayout->addRow(tr("&Object:"), this->pObjectEdit);
    formLayout->addRow(tr("Data &type:"), this->pDataTypeBox);
    formLayout->addRow(tr("&Data:"), this->pDataEdit);
    formLayout->addRow(tr("&SDO type:"), this->pSdoTypeBox);
    formLayout->addRow(tr("Abort Code:"), this->pAbortCodeLabel);

    /* create buttons */
    QHBoxLayout* buttonLayout = new QHBoxLayout();
    buttonLayout->addStretch(1);
    buttonLayout->addWidget(this->readButton);
    buttonLayout->addWidget(this->writeButton);
    buttonLayout->addWidget(closeButton);

    connect(this->readButton, SIGNAL(clicked()), this, SLOT(startRead()));
    connect(this->writeButton, SIGNAL(clicked()), this, SLOT(startWrite()));
    connect(closeButton, SIGNAL(clicked()), this, SLOT(reject()));
    connect(this->pDataTypeBox,
            SIGNAL(currentIndexChanged(int)),
            this,
            SLOT(dataTypeChanged(int)));
    connect(this,
            SIGNAL(sigUpdateData(const QString&)),
            this,
            SLOT(updateData(const QString&)),
            Qt::QueuedConnection);

    /* create main layout */
    mainLayout->addWidget(label);
    mainLayout->addLayout(formLayout);
    mainLayout->addStretch(0);
    mainLayout->addLayout(buttonLayout);

    setLayout(mainLayout);
    setWindowTitle("Perform SDO Transfer");
    setSizeGripEnabled(true);
}
Ejemplo n.º 3
0
template<typename SourceType> BMP_Status OLED::_displayBMP(SourceType &source, const int from_x, const int from_y, const int to_x, const int to_y)
{
  SourceType &f = source;
  f.seek(0);

  // File header, check magic number 'BM'
  if(f.read() != 'B' || f.read() != 'M')
    return BMP_INVALID_FORMAT;

  // Read DIB header with image properties
  f.seek(OFFS_DIB_HEADER);
  uint16_t dib_headersize = readLong(f);
  uint16_t width, height, bpp, compression;


  bool v2header = (dib_headersize == 12); // BMPv2 header, no compression, no additional options
  if(v2header) {
    width = readShort(f);
    height = readShort(f);
    if(readShort(f) != 1)
      return BMP_UNSUPPORTED_HEADER;
    bpp = readShort(f);
    compression = BMP_NoCompression;
  }
  else {
    width = readLong(f);
    height = readLong(f);
    if(readShort(f) != 1)
      return BMP_UNSUPPORTED_HEADER;
    bpp = readShort(f);
    compression = readLong(f);
  }

  // Verify image properties from header
  if(bpp > 24)
    return BMP_TOO_MANY_COLOURS;
  if(bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24)
    return BMP_UNSUPPORTED_COLOURS;

  if(!(compression == BMP_NoCompression
       || (compression == BMP_BITFIELDS && bpp == 16))) {
    return BMP_COMPRESSION_NOT_SUPPORTED;
  }

  // In case of the bitfields option, determine the pixel format. We support RGB565 & RGB555 only
  bool rgb565 = true;
  if(compression == BMP_BITFIELDS) {
    f.seek(0x36);
    uint16_t b = readLong(f);
    uint16_t g = readLong(f);
    uint16_t r = readLong(f);
    if(r == 0x001f && g == 0x07e0 && b == 0xf800)
      rgb565 = true;
    else if(r != 0x001f && g != 0x03e0 && b != 0x7c00)
      return BMP_UNSUPPORTED_COLOURS; // Not RGB555 either
  }

  if (width < from_x || height < from_y)
    return BMP_ORIGIN_OUTSIDE_IMAGE; // source in BMP is offscreen

  // Find the starting offset for the data in the first row
  f.seek(0x0a);
  uint32_t data_offs = readLong(f);

  assertCS();
  // Trim height to 128, anything bigger gets cut off, then set up row span in memory
  height = height - from_y;
  if(to_y + height > 128)
    height = 128-to_y;

  // Calculate outputtable width and set up column span in memory
  uint16_t out_width = width - from_x;
  if(to_x + out_width > 128)
    out_width = 128-to_x;

  // Calculate the width in bits of each row (rounded up to nearest byte)
  uint16_t row_bits = (width*bpp + 7) & ~7;
  // Calculate width in bytes (4-byte boundary aligned)
  uint16_t row_bytes = (row_bits/8 + 3) & ~3;

  startWrite(to_x,to_y,to_x+out_width-1,to_y+height-1,false);

  releaseCS();

  // Read colour palette to RAM. It's quite hefty to hold in RAM (512 bytes for a full 8-bit palette)
  // but don't have much choice as seeking back and forth on SD is painfully slow
  OLED_Colour *palette;
  if(bpp < 16) {
    uint16_t palette_size = 1<<bpp;
    palette = (OLED_Colour *)malloc(sizeof(OLED_Colour)*palette_size);
    f.seek(OFFS_DIB_HEADER + dib_headersize);
    for(uint16_t i = 0; i < palette_size; i++) {
      uint8_t pal[4];
      f.read(pal, v2header ? 3 : 4);
      palette[i].blue = pal[0] >> 3;
      palette[i].green = pal[1] >> 2;
      palette[i].red = pal[2] >> 3;
    }
  }
Ejemplo n.º 4
0
int OLED::drawChar(const int x, const int y, const char letter, const OLED_Colour colour, const OLED_Colour background)
{
  if (x <0 || y < 0 || x >= COLUMNS || y >= ROWS) return -1;

  struct FontHeader header;
  memcpy_P(&header, (void*)this->font, sizeof(FontHeader));

  uint8_t c = letter;
  if (c == ' ') {
    int charWide = charWidth(' ');
    this->drawFilledBox(x, y-1, x + charWide, y + header.height, background);
    return charWide;
  }
  uint8_t width = 0;
  uint8_t bytes = (header.height + 7) / 8; // Number of bytes in a single column

  uint16_t index = 0;

  if (c < header.firstChar || c >= (header.firstChar + header.charCount)) return 0;
  c -= header.firstChar;

  if (header.size == 0) {
    // zero length is flag indicating fixed width font (array does not contain width data entries)
    width = header.fixedWidth;
    index = sizeof(FontHeader) + c * bytes * width;
  } else {
    // variable width font, read width data, to get the index
    for (uint8_t i = 0; i < c; i++) {
      index += pgm_read_byte(this->font + sizeof(FontHeader) + i);
    }
    index = index * bytes + sizeof(FontHeader) + header.charCount;
    width = pgm_read_byte(this->font + sizeof(FontHeader) + c);
  }
  if (x < -width || y < -header.height)
    return width;

  assertCS();
  startWrite(x > 0 ? x : 0, y > 0 ? y : 0, 
             x+width > 127 ? 127 : x+width-1, y+header.height > 127 ? 127 : y+header.height-1,
             true);

  /* Characters are stored as follows:
   *
   * Each byte is up to 8 vertical pixels (LSB @ top)
   * Each row of bytes is adjacent
   * For fonts >8 pixels high, the bytes are strided by width
   *
   * ie for a font 16 pixels high and 8 pixels wide:
   *
   * P(0,0) P(0,1) P(1,0) P(1,1) P(2,0) P(2,1) P(3,0) P(3,1) ... etc
   *
   *
   * Things are made more annoying for OLED because we need to write to the display
   * bottom-to-top for each column, so striding backwards instead of forwards...
   */

  for(int16_t ox = 0; ox < width; ox++) {
    if(ox+x >= COLUMNS)
      break;
    int16_t oy = 0;
    for(int8_t byte_y = bytes-1; byte_y >= 0; byte_y--) {
      uint8_t data = pgm_read_byte(this->font + index + ox + byte_y * width);
      int8_t start_bit;
      int8_t end_bit;
      if(bytes == 1) {
        start_bit = header.height-1;
        end_bit = 0;
      }
      else {
        start_bit = 7;
        end_bit = (byte_y < bytes-1) ? 0: 7-((header.height-1)%8);
      }
      for(int8_t bit_y = start_bit; bit_y >= end_bit; bit_y--) {
        if(oy+y < ROWS && ox+x >= 0 && oy+y >= 0) {
          writeData( (data & 1<<bit_y) ? colour : background);
        }
        oy++;
        if(oy == header.height)
          break;
      }
    }
  }
  releaseCS();
  return width;
}
Ejemplo n.º 5
0
struct basic_epoll_event *http_server::headerClose()
{
    header.memcpy(CRLFCRLF, SSTRLEN(CRLFCRLF));
    return startWrite();
}
Ejemplo n.º 6
0
bool QRF24::write( const void* buf, quint8 len )
{
    bool result = false;

    // Begin the write
    startWrite(buf,len);

    // ------------
    // At this point we could return from a non-blocking write, and then call
    // the rest after an interrupt

    // Instead, we are going to block here until we get TX_DS (transmission completed and ack'd)
    // or MAX_RT (maximum retries, transmission failed).  Also, we'll timeout in case the radio
    // is flaky and we get neither.

    // IN the end, the send should be blocking.  It comes back in 60ms worst case, or much faster
    // if I tighted up the retry logic.  (Default settings will be 1500us.
    // Monitor the send
    quint8 observe_tx;
    quint8 status;
    uint32_t sent_at = millis();
    const unsigned long timeout = 500; //ms to wait for timeout

    do
    {
        status = readRegister(OBSERVE_TX,&observe_tx,1);

        if (debug)
            printf("%02X", observe_tx);
    }
    while( ! ( status & ( _BV(TX_DS) | _BV(MAX_RT) ) ) && ( millis() - sent_at < timeout ) );


    // The part above is what you could recreate with your own interrupt handler,
    // and then call this when you got an interrupt
    // ------------

    // Call this when you get an interrupt
    // The status tells us three things
    // * The send was successful (TX_DS)
    // * The send failed, too many retries (MAX_RT)
    // * There is an ack packet waiting (RX_DR)
    bool tx_ok, tx_fail;

    whatHappened(tx_ok,tx_fail,ack_payload_available);

    //printf("%u%u%u\r\n",tx_ok,tx_fail,ack_payload_available);

    result = tx_ok;
    if (debug)
        printf(result?"...OK.":"...Failed");

    // Handle the ack packet
    if ( ack_payload_available )
    {
        ack_payload_length = getDynamicPayloadSize();
        if (debug )
            printf("[AckPacket]/%d", ack_payload_length);
    }

    // Yay, we are done.

    // Power down
    powerDown();

    // Flush buffers (Is this a relic of past experimentation, and not needed anymore??)
    flushTx();

    return result;
}
Ejemplo n.º 7
0
void NetMessageSocket::writeError(const std::string& value)
{
	NetMessageWriter::writeError(writeBuffer_, value.c_str());
	startWrite();
}
Ejemplo n.º 8
0
void NetMessageSocket::writeArrayHeader(size_t numValues)
{
	NetMessageWriter::writeArrayHeader(writeBuffer_, numValues);
	startWrite();
}