示例#1
0
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);
}
示例#2
0
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 = 0;
  for (const iovec_t* vp = vec; vp->buf != NULL; vp++)
    len += vp->size;
  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);
  for (const iovec_t* vp = vec; vp->buf != NULL; vp++)
    spi.write(vp->buf, vp->size);
  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);
}