diff --git a/interface/esb.h b/interface/esb.h index d13b8ac1..8bf6c658 100644 --- a/interface/esb.h +++ b/interface/esb.h @@ -37,7 +37,7 @@ typedef struct esbPacket_s { union { uint8_t s1; struct { - uint8_t noack :1; + uint8_t ack :1; uint8_t pid :2; }; }; @@ -48,6 +48,7 @@ typedef struct esbPacket_s { * from uint32_t to uint8_t without lose of precision */ uint8_t rssi; unsigned int crc; + uint8_t match; } EsbPacket; typedef enum esbDatarate_e { esbDatarate250K=0, diff --git a/interface/syslink.h b/interface/syslink.h index 16cd241e..bf999104 100644 --- a/interface/syslink.h +++ b/interface/syslink.h @@ -44,12 +44,13 @@ bool syslinkSend(struct syslinkPacket *packet); // Defined packet types -#define SYSLINK_RADIO_RAW 0x00 -#define SYSLINK_RADIO_CHANNEL 0x01 -#define SYSLINK_RADIO_DATARATE 0x02 -#define SYSLINK_RADIO_CONTWAVE 0x03 -#define SYSLINK_RADIO_RSSI 0x04 -#define SYSLINK_RADIO_ADDRESS 0x05 +#define SYSLINK_RADIO_RAW 0x00 +#define SYSLINK_RADIO_CHANNEL 0x01 +#define SYSLINK_RADIO_DATARATE 0x02 +#define SYSLINK_RADIO_CONTWAVE 0x03 +#define SYSLINK_RADIO_RSSI 0x04 +#define SYSLINK_RADIO_ADDRESS 0x05 +#define SYSLINK_RADIO_RAW_BROADCAST 0x06 #define SYSLINK_PM_SOURCE 0x10 diff --git a/src/esb.c b/src/esb.c index 13be453f..dc7a624e 100644 --- a/src/esb.c +++ b/src/esb.c @@ -194,6 +194,7 @@ void esbInterruptHandler() pk = &rxPackets[rxq_head]; pk->rssi = (uint8_t) NRF_RADIO->RSSISAMPLE; pk->crc = NRF_RADIO->RXCRC; + pk->match = NRF_RADIO->RXMATCH; // If no more space available on RX queue, drop packet! if (((rxq_head+1)%RXQ_LEN) == rxq_tail) { @@ -202,7 +203,7 @@ void esbInterruptHandler() } // If this packet is a retry, send the same ACK again - if (isRetry(pk)) { + if (pk->ack && isRetry(pk)) { setupTx(true); return; } @@ -226,12 +227,19 @@ void esbInterruptHandler() curr_up = 1-curr_up; } - - if (!has_safelink || (pk->data[0]&0x04) != curr_down<<2) { - curr_down = 1-curr_down; - setupTx(false); - } else { - setupTx(true); + if (pk->ack) + { + if (!has_safelink || (pk->data[0]&0x04) != curr_down<<2) { + curr_down = 1-curr_down; + setupTx(false); + } else { + setupTx(true); + } + } else + { + // broadcast => no ack + NRF_RADIO->PACKETPTR = (uint32_t)&rxPackets[rxq_head]; + NRF_RADIO->TASKS_START = 1UL; } @@ -296,13 +304,17 @@ void esbInit() } // Radio address config - // Using logical address 0 so only BASE0 and PREFIX0 & 0xFF are used - NRF_RADIO->PREFIX0 = 0xC4C3C200UL | (bytewise_bitswap(address >> 32) & 0xFF); // Prefix byte of addresses 3 to 0 + // We use local addresses 0 and 1 + // * local address 0 is the unique address of the Crazyflie, used for 1-to-1 communication. + // This can be set dynamically and the current address is stored in EEPROM. + // * local address 1 is used for broadcasts + // This is currently 0xFFE7E7E7E7. + NRF_RADIO->PREFIX0 = 0xC4C3FF00UL | (bytewise_bitswap(address >> 32) & 0xFF); // Prefix byte of addresses 3 to 0 NRF_RADIO->PREFIX1 = 0xC5C6C7C8UL; // Prefix byte of addresses 7 to 4 NRF_RADIO->BASE0 = bytewise_bitswap((uint32_t)address); // Base address for prefix 0 - NRF_RADIO->BASE1 = 0x00C2C2C2UL; // Base address for prefix 1-7 + NRF_RADIO->BASE1 = 0xE7E7E7E7UL; // Base address for prefix 1-7 NRF_RADIO->TXADDRESS = 0x00UL; // Set device address 0 to use when transmitting - NRF_RADIO->RXADDRESSES = 0x01UL; // Enable device address 0 to use which receiving + NRF_RADIO->RXADDRESSES = (1<<0) | (1<<1); // Enable device address 0 and 1 to use which receiving // Packet configuration NRF_RADIO->PCNF0 = (PACKET0_S1_SIZE << RADIO_PCNF0_S1LEN_Pos) | diff --git a/src/main.c b/src/main.c index f9f38de0..9b1e568f 100644 --- a/src/main.c +++ b/src/main.c @@ -142,6 +142,7 @@ void mainloop() static int vbatSendTime; static int radioRSSISendTime; static uint8_t rssi; + static bool broadcast; while(1) { @@ -163,6 +164,8 @@ void mainloop() EsbPacket* packet = esbGetRxPacket(); //Store RSSI here so that we can send it to STM later rssi = packet->rssi; + // The received packet was a broadcast, if received on local address 1 + broadcast = packet->match == 1; memcpy(esbRxPacket.data, packet->data, packet->size); esbRxPacket.size = packet->size; esbReceived = true; @@ -186,7 +189,11 @@ void mainloop() { memcpy(slTxPacket.data, packet->data, packet->size); slTxPacket.length = packet->size; - slTxPacket.type = SYSLINK_RADIO_RAW; + if (broadcast) { + slTxPacket.type = SYSLINK_RADIO_RAW_BROADCAST; + } else { + slTxPacket.type = SYSLINK_RADIO_RAW; + } syslinkSend(&slTxPacket); }