コード例 #1
0
ファイル: RFM69.cpp プロジェクト: rrobinet/Cosa
int
RFM69::send(uint8_t dest, uint8_t port, const iovec_t* vec)
{
  // Sanity check the payload size
  if (UNLIKELY(vec == NULL)) return (EINVAL);
  size_t len = iovec_size(vec);
  if (UNLIKELY(len > PAYLOAD_MAX)) return (EMSGSIZE);

  // Check if a packet available. Should receive before send
  if (UNLIKELY(m_avail)) return (ENXIO);

  // Write frame header(length, dest, src, port) and payload
  spi.acquire(this);
    spi.begin();
      spi.transfer(REG_WRITE | FIFO);
      spi.transfer(len + HEADER_MAX);
      spi.transfer(dest);
      spi.transfer(m_addr.device);
      spi.transfer(port);
      spi.write(vec);
    spi.end();
  spi.release();

  // Trigger the transmit and await completion. Set standby mode
  m_done = false;
  set(TRANSMITTER_MODE);
  while (!m_done) yield();
  set(STANDBY_MODE);

  // Return total length of payload
  return (len);
}
コード例 #2
0
ファイル: CC1101.cpp プロジェクト: epatel/Cosa
int 
CC1101::send(uint8_t dest, uint8_t port, const iovec_t* vec)
{
  // Sanity check the payload size
  if (vec == NULL) return (-1);
  size_t len = iovec_size(vec);
  if (len > PAYLOAD_MAX) return (-1);

  // Wait for the device to become idle before writing the frame
  await(IDLE_MODE);

  // Write frame header(length, dest, src, port)
  spi.begin(this);
  loop_until_bit_is_clear(PIN, Board::MISO);
  write(TXFIFO, len + 3);
  write(TXFIFO, dest);
  write(TXFIFO, m_addr.device);
  write(TXFIFO, port);
  spi.end();

  // Write frame payload
  for (const iovec_t* vp = vec; vp->buf != NULL; vp++) {
    spi.begin(this);
    loop_until_bit_is_clear(PIN, Board::MISO);
    write(TXFIFO, vp->buf, vp->size);
    spi.end();
  }

  // Trigger the transmit
  strobe(STX);
  return (len);
}
コード例 #3
0
ファイル: NRF24L01P.cpp プロジェクト: jimblair/Cosa
int
NRF24L01P::send(uint8_t dest, uint8_t port, const iovec_t* vec)
{
  // Sanity check the payload size
  if (vec == NULL) return (-1);
  size_t len = iovec_size(vec);
  if (len > PAYLOAD_MAX) return (-1);

  // Setting transmit destination
  set_transmit_mode(dest);

  // Write source address and payload to the transmit fifo
  // Fix: Allow larger payload(30*3) with fragmentation
  spi.acquire(this);
    spi.begin();
      uint8_t command = ((dest != BROADCAST) 
			 ? W_TX_PAYLOAD 
			 : W_TX_PAYLOAD_NO_ACK);
      m_status = spi.transfer(command);
      spi.transfer(m_addr.device);
      spi.transfer(port);
      spi.write(vec);
    spi.end();
  spi.release();
  m_trans += 1;

  // Check for auto-acknowledge pipe(0), and address setup and enable
  if (dest != BROADCAST) {
    addr_t tx_addr(m_addr.network, dest);
    write(RX_ADDR_P0, &tx_addr, sizeof(tx_addr));  
    write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1) | _BV(ERX_P0)));
  }

  // Wait for transmission
  do {
    yield();
    read_status();
  } while (!m_status.tx_ds && !m_status.max_rt);
  bool data_sent = m_status.tx_ds;

  // Check for auto-acknowledge pipe(0) disable
  if (dest != BROADCAST) {
    write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1)));
  }

  // Reset status bits and read retransmission counter and update
  write(STATUS, _BV(MAX_RT) | _BV(TX_DS));
  observe_tx_t observe = read_observe_tx();
  m_retrans += observe.arc_cnt;

  // Check that the message was delivered
  if (data_sent) return (len);

  // Failed to delivery
  write(FLUSH_TX);
  m_drops += 1;
  return (-2);
}
コード例 #4
0
ファイル: ipc_dev.c プロジェクト: 01org/kernelflinger
int trusty_ipc_dev_send(struct trusty_ipc_dev *dev, handle_t chan,
                        const struct trusty_ipc_iovec *iovs, size_t iovs_cnt)
{
    int rc;
    size_t msg_size;
    volatile struct trusty_ipc_cmd_hdr *cmd;

    trusty_assert(dev);
    /* calc message length */
    msg_size = iovec_size(iovs, iovs_cnt);
    if (msg_size > dev->buf_size - sizeof(*cmd)) {
        /* msg is too big to fit provided buffer */
        trusty_error("%a: chan %d: msg is too long (%zu)\n", __func__,
                     chan, msg_size);
        return TRUSTY_ERR_MSG_TOO_BIG;
    }

    /* prepare command */
    cmd = dev->buf_vaddr;
    memset((void *)cmd, 0, sizeof(*cmd));
    cmd->opcode = QL_TIPC_DEV_SEND;
    cmd->handle = chan;

    /* copy in message data */
    cmd->payload_len = (uint32_t)msg_size;
    msg_size = iovec_to_buf(dev->buf_vaddr + sizeof(*cmd), dev->buf_size - sizeof(*cmd),
                          iovs,  iovs_cnt);
    trusty_assert(msg_size == (size_t)cmd->payload_len);

    /* call into secure os */
    rc = trusty_dev_exec_ipc(dev->tdev,
                             &dev->buf_ns, sizeof(*cmd) + cmd->payload_len);
    if (rc < 0) {
        trusty_error("%a: secure OS returned (%d)\n", __func__, rc);
        return TRUSTY_ERR_SECOS_ERR;
    }

    rc = check_response(dev, cmd, QL_TIPC_DEV_SEND);
    if (rc) {
        trusty_error("%a: send msg failed (%d)\n", __func__, rc);
    }

    return rc;
}
コード例 #5
0
ファイル: NRF24L01P.cpp プロジェクト: erictj/Cosa
int
NRF24L01P::send(uint8_t dest, uint8_t port, const iovec_t* vec)
{
  // Sanity check the payload size
  if (vec == NULL) return (-1);
  size_t len = iovec_size(vec);
  if (len > PAYLOAD_MAX) return (-1);

  // Setting transmit destination
  set_transmit_mode(dest);

  // Write source address and payload to the transmit fifo
  // Fix: Allow larger payload(30*3) with fragmentation
  spi.begin(this);
  m_status = spi.transfer(dest ? W_TX_PAYLOAD : W_TX_PAYLOAD_NO_ACK);
  spi.transfer(m_addr.device);
  spi.transfer(port);
  spi.write(vec);
  spi.end();
  m_trans += 1;

  // Wait for transmission
  do {
    Power::sleep(m_mode);
    read_status();
  } while (!m_status.tx_ds && !m_status.max_rt);
  bool data_sent = m_status.tx_ds;

  // Reset status bits and read retransmission counter and update
  write(STATUS, _BV(MAX_RT) | _BV(TX_DS));
  observe_tx_t observe = read_observe_tx();
  m_retrans += observe.arc_cnt;

  // Check that the message was delivered
  if (data_sent) return (len);

  // Failed to delivery
  write(FLUSH_TX);
  m_drops += 1;
  return (-2);
}