Beispiel #1
0
static void flasher_tx_handle(void) {
	static uint8_t first_tx = 1;

	/*
	 * If more than a second has passed since previous communication
	 * the bootloader will have left the flash mode by now so this is
	 * probably a new boot and a new flashing attempt.
	 */
	if ((uint32_t) (timer_read() - prev_txrx_ts) > F_CPU)
		first_tx = 1;

	/*
	 * Before any actual STK500v2 communication begins we need to
	 * attempt to reset the board to start the bootloader, and send it
	 * our radio address to return the ACK packets to.
	 */
	if (first_tx) {
		uint8_t ch, pkt[4];

		/*
		 * Our protocol requires any program running on the board
		 * to reset it if it receives a 0xff byte.
		 */
		ch = 0xff;
		nrf24_tx(&ch, 1);
		nrf24_tx_result_wait();

		/* Give the board time to reboot and enter the bootloader */
		my_delay(100);

		/* Finally send our address + pkt size as a separate packet */
		pkt[0] = eeprom_read(0);
		pkt[1] = eeprom_read(1);
		pkt[2] = eeprom_read(2);
		pkt[3] = MAX_PKT_SIZE;
		/* TODO: set the no-ACK bit, the remote board can't ACK yet */
		nrf24_tx(pkt, 4);
		nrf24_tx_result_wait();

		first_tx = 0;
	}

	prev_txrx_ts = timer_read();
}
Beispiel #2
0
void loop(void) {
	static uint8_t tx_cnt; /* Consecutive Tx packets counter */

	/*
	 * Note: all nrf24 calls are serialised in this function so as
	 * to avoid any concurrency issues.
	 */

	if (nrf24_rx_fifo_data()) {
		uint8_t pkt_len, pkt_buf[32], i;
#ifdef SEQN
		static uint8_t seqn = 0xff;
#endif

#ifdef FLASH_TOOL_MODE
		flasher_rx_handle();
#endif

		nrf24_rx_read(pkt_buf, &pkt_len);

#ifdef SEQN
		if (pkt_buf[0] != seqn) {
			seqn = pkt_buf[0];
			for (i = 1; i < pkt_len; i ++)
				serial_write1(pkt_buf[i]);
		}
#else
		for (i = 0; i < pkt_len; i ++)
			serial_write1(pkt_buf[i]);
#endif

		tx_cnt = 0;
	}

	if (tx_fifo.len) { /* .len access should be atomic */
		uint8_t pkt_len, pkt_buf[MAX_PKT_SIZE], split;
#ifdef SEQN
		static uint8_t seqn = 0x00;
		uint8_t count = 128;
#define		MAX_PLD_SIZE	(MAX_PKT_SIZE - 1)

		pkt_buf[0] = seqn ++;
#else
		uint8_t count = 2;
#define		MAX_PLD_SIZE	MAX_PKT_SIZE
#endif

#ifdef FLASH_TOOL_MODE
		flasher_tx_handle();
#endif

		tx_cnt ++;

		cli();
		pkt_len = min(tx_fifo.len, MAX_PLD_SIZE);
		sei();

		/* HACK */
		if (tx_cnt == 2 && MAX_PLD_SIZE > 2 && pkt_len == MAX_PLD_SIZE)
			pkt_len = MAX_PLD_SIZE - 2;
		else if (MAX_PLD_SIZE > 2 && tx_cnt == 3)
			pkt_len = 1;

		split = min(pkt_len,
				(uint16_t) (~tx_fifo.start & FIFO_MASK) + 1);

#define START (MAX_PKT_SIZE - MAX_PLD_SIZE)
		memcpy(pkt_buf + START, tx_fifo.data +
				(tx_fifo.start & FIFO_MASK), split);
		memcpy(pkt_buf + START + split, tx_fifo.data, pkt_len - split);
		/*
		 * Or we could just do pkt_buf = tx_fifo.data + ...;
		 * pkt_len = split;
		 */

		cli();
		tx_fifo.len -= pkt_len;
		tx_fifo.start += pkt_len;
		sei();

		while (-- count) {
			/* Don't flood the remote end with the comms */
			my_delay(4);

			nrf24_tx(pkt_buf, pkt_len + START);
			if (!nrf24_tx_result_wait())
				break;
		}
	}
}
bool RHReliableDatagram::sendtoWait(uint8_t *buf, uint8_t len,
		uint8_t address) {
	update_tx_addr(address);
	nrf24_tx(buf, len);
	return !nrf24_tx_result_wait();
}