This commit is contained in:
pascallanger 2016-11-16 21:17:03 +00:00 committed by GitHub
parent 6ad9fb8f27
commit 7c22110c96

View File

@ -1,202 +1,193 @@
/* /*
This project is free software: you can redistribute it and/or modify This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful, Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>. along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/ */
// Last sync with hexfet new_protocols/slt_nrf24l01.c dated 2015-02-13 // Last sync with deviation main github branch
#if defined(SLT_NRF24L01_INO) #if defined(SLT_NRF24L01_INO)
#include "iface_nrf24l01.h" #include "iface_nrf24l01.h"
// For code readability // For code readability
#define SLT_PAYLOADSIZE 7 #define SLT_PAYLOADSIZE 7
#define SLT_NFREQCHANNELS 15 #define SLT_NFREQCHANNELS 15
#define SLT_TXID_SIZE 4 #define SLT_TXID_SIZE 4
enum { enum {
SLT_INIT2 = 0, SLT_BIND=0,
SLT_BIND, SLT_DATA1,
SLT_DATA1, SLT_DATA2,
SLT_DATA2, SLT_DATA3
SLT_DATA3 };
};
static void __attribute__((unused)) SLT_init()
static void __attribute__((unused)) SLT_init() {
{ NRF24L01_Initialize();
NRF24L01_Initialize(); NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4-byte RX/TX address
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4-byte RX/TX address NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // Disable auto retransmit
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // Disable auto retransmit NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 4); // bytes of data payload for pipe 1
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 4); // bytes of data payload for pipe 1 NRF24L01_SetBitrate(NRF24L01_BR_250K); // 256kbps
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 256kbps NRF24L01_SetPower();
NRF24L01_SetPower(); NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\xC3\xC3\xAA\x55", 4);
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\xC3\xC3\xAA\x55", 4); NRF24L01_FlushRx();
NRF24L01_FlushRx(); NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE);
} NRF24L01_FlushTx();
// Turn radio power on
static void __attribute__((unused)) SLT_init2() NRF24L01_SetTxRxMode(TX_EN);
{ }
NRF24L01_FlushTx();
packet_sent = 0; static void __attribute__((unused)) SLT_set_freq(void)
hopping_frequency_no = 0; {
// Frequency hopping sequence generation
// Turn radio power on for (uint8_t i = 0; i < SLT_TXID_SIZE; ++i)
NRF24L01_SetTxRxMode(TX_EN); {
} uint8_t next_i = (i+1) % SLT_TXID_SIZE; // is & 3 better than % 4 ?
uint8_t base = i < 2 ? 0x03 : 0x10;
static void __attribute__((unused)) SLT_set_tx_id(void) hopping_frequency[i*4 + 0] = (rx_tx_addr[i] & 0x3f) + base;
{ hopping_frequency[i*4 + 1] = (rx_tx_addr[i] >> 2) + base;
// Frequency hopping sequence generation hopping_frequency[i*4 + 2] = (rx_tx_addr[i] >> 4) + (rx_tx_addr[next_i] & 0x03)*0x10 + base;
for (uint8_t i = 0; i < 4; ++i) if (i*4 + 3 < SLT_NFREQCHANNELS) // guard for 16 channel
{ hopping_frequency[i*4 + 3] = (rx_tx_addr[i] >> 6) + (rx_tx_addr[next_i] & 0x0f)*0x04 + base;
uint8_t next_i = (i+1) % 4; // is & 3 better than % 4 ? }
uint8_t base = i < 2 ? 0x03 : 0x10;
hopping_frequency[i*4 + 0] = (rx_tx_addr[i] & 0x3f) + base; // unique
hopping_frequency[i*4 + 1] = (rx_tx_addr[i] >> 2) + base; for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
hopping_frequency[i*4 + 2] = (rx_tx_addr[i] >> 4) + (rx_tx_addr[next_i] & 0x03)*0x10 + base; {
if (i*4 + 3 < SLT_NFREQCHANNELS) // guard for 16 channel uint8_t done = 0;
hopping_frequency[i*4 + 3] = (rx_tx_addr[i] >> 6) + (rx_tx_addr[next_i] & 0x0f)*0x04 + base; while (!done)
} {
done = 1;
// unique for (uint8_t j = 0; j < i; ++j)
uint8_t done = 0; if (hopping_frequency[i] == hopping_frequency[j])
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i) {
while (!done) done = 0;
{ hopping_frequency[i] += 7;
done = 1; if (hopping_frequency[i] >= 0x50)
for (uint8_t j = 0; j < i; ++j) hopping_frequency[i] = hopping_frequency[i] - 0x50 + 0x03;
if (hopping_frequency[i] == hopping_frequency[j]) }
{ }
done = 0; }
hopping_frequency[i] += 7; }
if (hopping_frequency[i] >= 0x50)
hopping_frequency[i] = hopping_frequency[i] - 0x50 + 0x03; static void __attribute__((unused)) SLT_wait_radio()
} {
} if (packet_sent)
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) ;
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 4); packet_sent = 0;
} }
static void __attribute__((unused)) SLT_wait_radio() static void __attribute__((unused)) SLT_send_data(uint8_t *data, uint8_t len)
{ {
if (packet_sent) SLT_wait_radio();
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))) ; NRF24L01_FlushTx();
packet_sent = 0; NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT));
} NRF24L01_WritePayload(data, len);
//NRF24L01_PulseCE();
static void __attribute__((unused)) SLT_send_data(uint8_t *data, uint8_t len) packet_sent = 1;
{ }
SLT_wait_radio();
NRF24L01_FlushTx(); static void __attribute__((unused)) SLT_build_packet()
NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT)); {
NRF24L01_WritePayload(data, len); // aileron, elevator, throttle, rudder, gear, pitch
//NRF24L01_PulseCE(); uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed
packet_sent = 1; for (uint8_t i = 0; i < 4; ++i)
} {
uint16_t v = convert_channel_10b(CH_AETR[i]);
static void __attribute__((unused)) SLT_build_packet() packet[i] = v;
{ e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
// aileron, elevator, throttle, rudder, gear, pitch }
uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed // Extra bits for AETR
for (uint8_t i = 0; i < 4; ++i) { packet[4] = e;
uint16_t v = convert_channel_10b(CH_AETR[i]); // 8-bit channels
packet[i] = v; packet[5] = convert_channel_8b(AUX1);
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0); packet[6] = convert_channel_8b(AUX2);
}
// Extra bits for AETR // Set radio channel - once per packet batch
packet[4] = e; NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
// 8-bit channels if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
packet[5] = convert_channel_8b(AUX1); hopping_frequency_no = 0;
packet[6] = convert_channel_8b(AUX2); }
// Set radio channel - once per packet batch static void __attribute__((unused)) SLT_send_bind_packet()
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); {
if (++hopping_frequency_no >= SLT_NFREQCHANNELS) SLT_wait_radio();
hopping_frequency_no = 0; BIND_IN_PROGRESS; //Limit TX power to bind level
} NRF24L01_SetPower();
BIND_DONE;
static void __attribute__((unused)) SLT_send_bind_packet() NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", 4);
{
SLT_wait_radio(); NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x50);
BIND_IN_PROGRESS; // autobind protocol SLT_send_data(rx_tx_addr, SLT_TXID_SIZE);
NRF24L01_SetPower();
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", 4); // W²ait until the packet's sent before changing TX address!
SLT_wait_radio();
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x50);
SLT_send_data(rx_tx_addr, 4); NRF24L01_SetPower(); //Change power back to normal level
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE);
// NB: we should wait until the packet's sent before changing TX address! }
SLT_wait_radio();
uint16_t SLT_callback()
BIND_DONE; {
NRF24L01_SetPower(); uint16_t delay_us = 20000; // 3 packets with 1ms intervals every 22ms
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 4); switch (phase)
} {
case SLT_BIND:
uint16_t SLT_callback() SLT_send_bind_packet();
{ phase = SLT_DATA1;
uint16_t delay_us = 20000; // 3 packets with 1ms intervals every 22ms delay_us = 19000;
switch (phase) break;
{ case SLT_DATA1:
case SLT_INIT2: SLT_build_packet();
SLT_init2(); SLT_send_data(packet, SLT_PAYLOADSIZE);
phase = SLT_BIND; phase = SLT_DATA2;
delay_us = 150; delay_us = 1000;
break; break;
case SLT_BIND: case SLT_DATA2:
SLT_send_bind_packet(); SLT_send_data(packet, SLT_PAYLOADSIZE);
phase = SLT_DATA1; phase = SLT_DATA3;
delay_us = 19000; delay_us = 1000;
break; break;
case SLT_DATA1: case SLT_DATA3:
SLT_build_packet(); SLT_send_data(packet, SLT_PAYLOADSIZE);
SLT_send_data(packet, 7); if (++packet_count >= 100)
phase = SLT_DATA2; {
delay_us = 1000; packet_count = 0;
break; phase = SLT_BIND;
case SLT_DATA2: delay_us = 1000;
SLT_send_data(packet, 7); }
phase = SLT_DATA3; else
delay_us = 1000; {
break; NRF24L01_SetPower(); // Set tx_power
case SLT_DATA3: phase = SLT_DATA1;
SLT_send_data(packet, 7); }
if (++counter >= 100) break;
{ }
counter = 0; return delay_us;
phase = SLT_BIND; }
delay_us = 1000;
} uint16_t initSLT()
else {
{ packet_count = 0;
NRF24L01_SetPower(); // Set tx_power packet_sent = 0;
phase = SLT_DATA1; hopping_frequency_no = 0;
} SLT_set_freq();
break; SLT_init();
} phase = SLT_BIND;
return delay_us; return 50000;
} }
uint16_t initSLT() #endif
{
counter = 0;
SLT_init();
phase = SLT_INIT2;
SLT_set_tx_id();
return 50000;
}
#endif