Esempio n. 1
0
/* This low-level send bytes function is NON-BLOCKING; blocking behavior, with
 * a timeout, is implemented in usercode (or in the Wirish C++ high level
 * implementation).
 *
 * This function will quickly copy up to 64 bytes of data (out of an
 * arbitrarily large buffer) into the USB peripheral TX buffer and return the
 * number placed in that buffer. It is up to usercode to divide larger packets
 * into 64-byte chunks to guarantee delivery. Use usbGetCountTx() to determine
 * whether the bytes were ACTUALLY recieved by the host or just transfered to
 * the buffer.
 *
 * The function will return -1 if it doesn't think that the USB host is
 * "connected", but it can't detect this state robustly. "Connected" in this
 * context means that an actual program on the Host operating system is
 * connected to the virtual COM/ttyACM device and is recieving the bytes; the
 * Host operating system is almost always configured and keeping this endpoint
 * alive, but the bytes never get read out of the endpoint buffer.
 *
 * The behavior of this function is subtle and frustrating; it has gone through
 * many simpler and cleaner implementation that frustratingly don't work cross
 * platform.
 *
 * */
uint16 usbSendBytes(uint8* sendBuf, uint16 len) {

    uint16 loaded = 0;

    if (bDeviceState != CONFIGURED || (!usbGetDTR() && !usbGetRTS())) {
        // Indicates to caller to stop trying, were not configured/connected
        // The DTR and RTS lines are handled differently on major platforms, so
        // the above logic is unreliable
        return 0;
    }

    // Due to a variety of shit this is how we roll; all buffering etc is pushed
    // upstream
    if (countTx) {
        return 0;
    }

    // We can only put VCOM_TX_EPSIZE bytes in the buffer
    if(len > VCOM_TX_EPSIZE) {
        loaded = VCOM_TX_EPSIZE;
    } else {
        loaded = len;
    }

    // Try to load some bytes if we can
    if (loaded) {
        UserToPMABufferCopy(sendBuf,VCOM_TX_ADDR + countTx, loaded);
        _SetEPTxCount(VCOM_TX_ENDP, countTx+loaded);
        _SetEPTxValid(VCOM_TX_ENDP);
        countTx += loaded;
    }

    return loaded;
}
Esempio n. 2
0
/* This low-level send bytes function is NON-BLOCKING; blocking behavior, with
 * a timeout, is implemented in usercode (or in the Wirish C++ high level
 * implementation).
 *
 * This function will quickly copy up to 64 bytes of data (out of an
 * arbitrarily large buffer) into the USB peripheral TX buffer and return the
 * number placed in that buffer. It is up to usercode to divide larger packets
 * into 64-byte chunks to guarantee delivery.
 *
 *
 */
void usbBlockingSendByte(char ch) {
    while (countTx);
    UserToPMABufferCopy((uint8*)&ch,VCOM_TX_ADDR,1);
    _SetEPTxCount(VCOM_TX_ENDP,1);
    _SetEPTxValid(VCOM_TX_ENDP);
    countTx = 1;
    while (countTx);
}
Esempio n. 3
0
uint32 usbSendBytes(const uint8* sendBuf, uint32 len) {
  /* Last transmission hasn't finished, abort */
  if (countTx) {
    return 0;
  }

  // We can only put VCOM_TX_EPSIZE bytes in the buffer
  if (len > VCOM_TX_EPSIZE / 2) {
    len = VCOM_TX_EPSIZE / 2;
  }

  // Try to load some bytes if we can
  if (len) {
    UserToPMABufferCopy(sendBuf, VCOM_TX_ADDR, len);
    _SetEPTxCount(VCOM_TX_ENDP, len);
    countTx += len;
    _SetEPTxValid(VCOM_TX_ENDP);
  }

  return len;
}