Compare commits

...

6 Commits

Author SHA1 Message Date
pascallanger
7327265e55 Update Compiling.md 2025-02-22 11:23:15 +01:00
pascallanger
496c07943f KAMTOM new surface protocol
Missing low batt telem
2025-02-21 21:46:18 +01:00
pascallanger
af87b0f6d1 Update UDIRC_ccnrf.ino 2025-02-19 17:16:04 +01:00
pascallanger
2918e63fb4 XN297Emu add ReSendPayload 2025-02-19 11:54:29 +01:00
pascallanger
ed63ef7efe Update UDIRC_ccnrf.ino 2025-02-19 11:33:17 +01:00
pascallanger
36d25c7773 Update UDIRC_ccnrf.ino 2025-02-19 11:21:26 +01:00
13 changed files with 291 additions and 53 deletions

View File

@@ -229,6 +229,6 @@
98,0,Kyosho3,ASF,0
100,0,YuXiang,Std,0,Lock,Rate,Land,Manual,Flip,Mode,Pitch
102,0,JIABAILE,Std,0,Speed,Light,Flash
102,1,JIABAILE,Gyro,0,Speed,Light,Flash,Tr_ST
102,1,JIABAILE,Gyro,0,Speed,Light,Flash,ST_Tr
103,0,H36,Std,1,Flip,HLess,RTH
104,0,KAMTOM_NRF24L01_INO,Std,1,
104,0,KAMTOM,Std,0,ST_Tr,TH_Tr,TH_DR

View File

@@ -0,0 +1,179 @@
/*
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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(KAMTOM_NRF24L01_INO)
#include "iface_xn297.h"
//#define FORCE_KAMTOM_ORIGINAL_ID
#define KAMTOM_PAYLOAD_SIZE 16
#define KAMTOM_RF_NUM_CHANNELS 4
#define KAMTOM_BIND_COUNT 2000
#define KAMTOM_WRITE_TIME 650
#define KAMTOM_BIND_CHANNEL 0x28 //40
#define KAMTOM_PACKET_PERIOD 3585
enum {
KAMTOM_DATA,
KAMTOM_RX,
};
static void __attribute__((unused)) KAMTOM_send_packet()
{
if(bind_counter)
{
bind_counter--;
if(!bind_counter)
BIND_DONE;
}
memset(packet, 0x00, 16);
if(IS_BIND_DONE)
{//Normal
XN297_Hopping(hopping_frequency_no);
hopping_frequency_no++;
hopping_frequency_no &= 3;
//RXID
packet[0] = rx_tx_addr[0];
packet[2] = rx_tx_addr[1];
//Next RF channel
packet[1] = hopping_frequency[hopping_frequency_no];
//Channels and trims
for(uint8_t i=0; i<6; i++)
{
packet[4+i] = convert_channel_s8b(CH_TAER[i]);
if(i>3) //ST_TR and TH_TR
packet[4+i] >>= 2;
}
//packet[11] = 0x00; //??
//TH_DR
packet[12] = convert_channel_16b_limit(CH7,0x25,0x64);
}
else
{
packet[1] = KAMTOM_BIND_CHANNEL;
memcpy(&packet[4],hopping_frequency,4);
packet[12] = 0xA5;
}
packet[10] = 0x40; //??
//Checksum
uint16_t sum = packet[1];
for(uint8_t i=4;i<13;i++)
sum += packet[i];
packet[13] = sum;
packet[3] = (sum>>6) & 0xFC;
//TXID
packet[14] = rx_tx_addr[2];
packet[15] = rx_tx_addr[3];
// Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, KAMTOM_PAYLOAD_SIZE,false);
#if 0
//def DEBUG_SERIAL
for(uint8_t i=0; i < KAMTOM_PAYLOAD_SIZE; i++)
debug("%02X ", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) KAMTOM_initialize_txid()
{
calc_fh_channels(4);
#ifdef FORCE_KAMTOM_ORIGINAL_ID
rx_tx_addr[0] = 0xC7;
rx_tx_addr[1] = 0x78;
rx_tx_addr[2] = 0x2C;
rx_tx_addr[3] = 0x25;
hopping_frequency[0] = 59;
hopping_frequency[1] = 59;
hopping_frequency[2] = 71;
hopping_frequency[3] = 65;
#endif
}
static void __attribute__((unused)) KAMTOM_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
//Address
XN297_SetTXAddr((uint8_t*)"\xCC\xDD\xEE\xDD", 4);
XN297_SetRXAddr((uint8_t*)"\xCC\xDD\xEE\xDD", KAMTOM_PAYLOAD_SIZE);
XN297_RFChannel(KAMTOM_BIND_CHANNEL);
}
uint16_t KAMTOM_callback()
{
static bool rx=false;
switch(phase)
{
case KAMTOM_DATA:
rx = XN297_IsRX();
XN297_SetTxRxMode(TXRX_OFF);
#ifdef MULTI_SYNC
telemetry_set_input_sync(KAMTOM_PACKET_PERIOD);
#endif
KAMTOM_send_packet();
if(rx)
{
uint8_t val=XN297_ReadEnhancedPayload(packet_in, KAMTOM_PAYLOAD_SIZE);
if(val==KAMTOM_PAYLOAD_SIZE)
{
BIND_DONE;
if(packet_in[0] == 0xA0 && packet_in[14] == rx_tx_addr[2] && packet_in[15] == rx_tx_addr[3])
{
rx_tx_addr[0] = packet_in[9];
rx_tx_addr[1] = packet_in[10];
//if(packet_in[1] == 0x03) // low voltage
}
#if 0
for(uint8_t i=0; i < KAMTOM_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
debugln();
#endif
}
}
phase++;
return KAMTOM_WRITE_TIME;
default: //KAMTOM_RX
//{ // Wait for packet to be sent before switching to receive mode
// uint16_t start=(uint16_t)micros();
// while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
// if(XN297_IsPacketSent())
// break;
//}
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = KAMTOM_DATA;
return KAMTOM_PACKET_PERIOD - KAMTOM_WRITE_TIME;
}
return 0;
}
void KAMTOM_init()
{
KAMTOM_initialize_txid();
KAMTOM_RF_init();
bind_counter = KAMTOM_BIND_COUNT;
phase = KAMTOM_DATA;
hopping_frequency_no = 0;
}
#endif

View File

@@ -99,3 +99,4 @@
100,YuXiang
102,JIABAILE,STD,GYRO
103,H36
104,KAMTOM

View File

@@ -115,6 +115,7 @@ const char STR_KYOSHO3[] ="Kyosho3";
const char STR_YUXIANG[] ="YuXiang";
const char STR_UDIRC[] ="UDIRC";
const char STR_JIABAILE[] ="JIABAILE";
const char STR_KAMTOM[] ="KAMTOM";
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
@@ -391,6 +392,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(JOYSWAY_A7105_INO)
{PROTO_JOYSWAY, STR_JOYSWAY, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_A7105, JOYSWAY_init, JOYSWAY_callback },
#endif
#if defined(KAMTOM_NRF24L01_INO)
{PROTO_KAMTOM, STR_KAMTOM, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, KAMTOM_init, KAMTOM_callback },
#endif
#if defined(KF606_CCNRF_INO)
{PROTO_KF606, STR_KF606, STR_SUBTYPE_KF606, 3, OPTION_RFTUNE, 0, 0, SW_NRF, KF606_init, KF606_callback },
#endif

View File

@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 4
#define VERSION_PATCH_LEVEL 33
#define VERSION_PATCH_LEVEL 34
#define MODE_SERIAL 0
@@ -131,6 +131,7 @@ enum PROTOCOLS
PROTO_UDIRC = 101, // =>CC2500 & NRF24L01
PROTO_JIABAILE = 102, // =>NRF24L01
PROTO_H36 = 103, // =>NRF24L01
PROTO_KAMTOM = 104, // =>NRF24L01
PROTO_NANORF = 126, // =>NRF24L01
PROTO_TEST = 127, // =>CC2500

View File

@@ -169,7 +169,7 @@ uint16_t SGF22_callback()
}
else
{//send 3 times in total the same packet
NRF24L01_Strobe(REUSE_TX_PL);
XN297_ReSendPayload();
phase++;
if(phase > 2)
{

View File

@@ -12,6 +12,8 @@ Multiprotocol is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
//Models: UDIRC UD160x(PRO), Pinecone Models SG-160x, Eachine EAT15
#if defined(UDIRC_CCNRF_INO)
#include "iface_xn297.h"
@@ -20,12 +22,15 @@ Multiprotocol is distributed in the hope that it will be useful,
#define UDIRC_PAYLOAD_SIZE 15
#define UDIRC_RF_NUM_CHANNELS 4
#define UDIRC_PACKET_PERIOD 8000
#define UDIRC_PACKET_PERIOD 21000
#define UDIRC_BIND_COUNT 2000
#define UDIRC_P1_P2_TIME 5000
#define UDIRC_WRITE_TIME 1500
enum {
UDIRC_DATA=0,
UDIRC_DATA1=0,
UDIRC_DATA2,
UDIRC_DATA3,
UDIRC_RX,
};
@@ -50,6 +55,7 @@ static void __attribute__((unused)) UDIRC_send_packet()
}
else
{//Switch to normal
rf_ch_num = 1;
BIND_DONE;
XN297_SetTXAddr(rx_tx_addr, 5);
XN297_SetRXAddr(rx_tx_addr, UDIRC_PAYLOAD_SIZE);
@@ -58,21 +64,20 @@ static void __attribute__((unused)) UDIRC_send_packet()
if(!bind_counter)
{//Normal
packet[0] = 0x08;
packet[1] = convert_channel_16b_limit(AILERON,0,200); //ST
packet[2] = convert_channel_16b_limit(THROTTLE,0,200); //TH
packet[3] = convert_channel_16b_limit(ELEVATOR,0,200); //CH4
packet[4] = convert_channel_16b_limit(RUDDER,0,200); //CH3
//Channels SG-16xx: ST/TH/CH4 /CH3 /UNK/UNK/UNK/UNK/GYRO/ST_TRIM/ST_DR
//Channels EAT15 : ST/TH/RATE/LIGHT/UNK/UNK/UNK/UNK/GYRO/ST_TRIM/ST_DR
for(uint8_t i=0; i<12; i++)
packet[i+1] = convert_channel_16b_limit(i,0,200);
//Just for now let's set the additional channels to 0
packet[5] = packet[6] = packet[7] = packet[8] = 0;
}
//packet[5/6..8] = 00 unknown
packet[9] = convert_channel_16b_limit(CH5,0,200); //ESP
packet[10] = convert_channel_16b_limit(CH6,0,200); //ST_TRIM
packet[11] = convert_channel_16b_limit(CH7,0,200); //ST_DR
packet[12] = GET_FLAG(CH8_SW, 0x40) //TH.REV
|GET_FLAG(CH9_SW, 0x80); //ST.REV
//packet[13] = 00 unknown
packet[12] = GET_FLAG(CH12_SW, 0x40) //TH.REV
|GET_FLAG(CH13_SW, 0x80); //ST.REV
//packet[13] = 00; //Unknown, future flags?
for(uint8_t i=0;i<UDIRC_PAYLOAD_SIZE-1;i++)
packet[14] += packet[i];
// Send
XN297_SetFreqOffset();
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, UDIRC_PAYLOAD_SIZE,false);
@@ -86,11 +91,22 @@ static void __attribute__((unused)) UDIRC_send_packet()
static void __attribute__((unused)) UDIRC_initialize_txid()
{
#ifdef FORCE_UDIRC_ORIGINAL_ID
if(RX_num)
{
rx_tx_addr[0] = 0xD0;
rx_tx_addr[1] = 0x06;
rx_tx_addr[2] = 0x00;
rx_tx_addr[3] = 0x00;
rx_tx_addr[4] = 0x81;
}
else
{
rx_tx_addr[0] = 0xF6;
rx_tx_addr[1] = 0x96;
rx_tx_addr[2] = 0x01;
rx_tx_addr[3] = 0x00;
rx_tx_addr[4] = 0x81;
}
hopping_frequency[0] = 45;
hopping_frequency[1] = 59;
hopping_frequency[2] = 52;
@@ -112,7 +128,7 @@ uint16_t UDIRC_callback()
bool rx;
switch(phase)
{
case UDIRC_DATA:
case UDIRC_DATA1:
rx = XN297_IsRX();
XN297_SetTxRxMode(TXRX_OFF);
#ifdef MULTI_SYNC
@@ -122,26 +138,25 @@ uint16_t UDIRC_callback()
if(rx)
{
uint8_t val=XN297_ReadEnhancedPayload(packet_in, UDIRC_PAYLOAD_SIZE);
debug("RX %d",val);
if(val==0)
debug("RX(%d):",val);
if(val != 255)
{
rf_ch_num = 1;
if(bind_counter)
bind_counter=1;
}
else
{
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < UDIRC_PAYLOAD_SIZE; i++)
debug(" %02X", packet_in[i]);
debugln();
#endif
}
//else
// debug(" NOK");
debugln("");
}
phase++;
return UDIRC_P1_P2_TIME;
case UDIRC_DATA2:
//Resend packet
XN297_ReSendPayload();
phase++;
return UDIRC_WRITE_TIME;
default: //UDIRC_RX
//Wait for the packet transmission to finish
@@ -149,8 +164,8 @@ uint16_t UDIRC_callback()
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = UDIRC_DATA;
return UDIRC_PACKET_PERIOD - UDIRC_WRITE_TIME;
phase = UDIRC_DATA1;
return UDIRC_PACKET_PERIOD - UDIRC_P1_P2_TIME - UDIRC_WRITE_TIME;
}
return 0;
}
@@ -161,7 +176,7 @@ void UDIRC_init()
UDIRC_RF_init();
bind_counter = IS_BIND_IN_PROGRESS ? UDIRC_BIND_COUNT : 1;
phase = UDIRC_DATA;
phase = UDIRC_DATA1;
hopping_frequency_no = 0;
rf_ch_num = 0;
}

View File

@@ -326,6 +326,7 @@
#undef HONTAI_NRF24L01_INO
#undef JIABAILE_NRF24L01_INO
#undef JJRC345_NRF24L01_INO
#undef KAMTOM_NRF24L01_INO
#undef KN_NRF24L01_INO
#undef KYOSHO2_NRF24L01_INO
#undef LOLI_NRF24L01_INO
@@ -393,6 +394,7 @@
#undef SHENQI_NRF24L01_INO
#undef JIABAILE_NRF24L01_INO
#undef UDIRC_CCNRF_INO
#undef KAMTOM_NRF24L01_INO
#endif
#ifdef MULTI_SURFACE

View File

@@ -207,6 +207,27 @@ static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State mode)
#endif
}
#ifdef CC2500_INSTALLED
uint8_t XN297_Buffer[32];
uint8_t XN297_Buffer_Len = 0;
static void __attribute__((unused)) XN297_SendCC2500Payload()
{
// stop TX/RX
CC2500_Strobe(CC2500_SIDLE);
// flush tx FIFO
CC2500_Strobe(CC2500_SFTX);
// packet length
CC2500_WriteReg(CC2500_06_PKTLEN, XN297_Buffer_Len + 4); // Packet len, fix packet len
// xn297L preamble
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x0C\x71\x0F\x55", 4);
// xn297 packet
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, XN297_Buffer, XN297_Buffer_Len);
// transmit
CC2500_Strobe(CC2500_STX);
}
#endif
static void __attribute__((unused)) XN297_SendPayload(uint8_t* msg, uint8_t len)
{
#ifdef NRF24L01_INSTALLED
@@ -220,22 +241,25 @@ static void __attribute__((unused)) XN297_SendPayload(uint8_t* msg, uint8_t len)
#ifdef CC2500_INSTALLED
if(xn297_rf == XN297_CC2500)
{
// stop TX/RX
CC2500_Strobe(CC2500_SIDLE);
// flush tx FIFO
CC2500_Strobe(CC2500_SFTX);
// packet length
CC2500_WriteReg(CC2500_06_PKTLEN, len + 4); // Packet len, fix packet len
// xn297L preamble
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x0C\x71\x0F\x55", 4);
// xn297 packet
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, msg, len);
// transmit
CC2500_Strobe(CC2500_STX);
memcpy(XN297_Buffer, msg, len);
XN297_Buffer_Len = len;
XN297_SendCC2500Payload();
}
#endif
}
static void __attribute__((unused)) XN297_ReSendPayload()
{
#ifdef NRF24L01_INSTALLED
if(xn297_rf == XN297_NRF)
NRF24L01_Strobe(NRF24L01_E3_REUSE_TX_PL);
#endif
#ifdef CC2500_INSTALLED
if(xn297_rf == XN297_CC2500)
XN297_SendCC2500Payload();
#endif
}
static void __attribute__((unused)) XN297_WritePayload(uint8_t* msg, uint8_t len)
{
uint8_t buf[32];
@@ -329,9 +353,9 @@ static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t* msg, uin
last++;
buf[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload
}
if(xn297_scramble_enabled)
buf[last] ^= xn297_scramble[scramble_index++] & 0xc0;
}
// crc
if (xn297_crc)
@@ -351,8 +375,7 @@ static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t* msg, uin
buf[last++] = (crc & 0xff) << 6;
}
pid++;
if(pid>3)
pid=0;
pid &= 0x03;
// send packet
XN297_SendPayload(buf, last);

View File

@@ -246,6 +246,7 @@
#define HONTAI_NRF24L01_INO
#define JIABAILE_NRF24L01_INO
#define JJRC345_NRF24L01_INO
#define KAMTOM_NRF24L01_INO
#define KN_NRF24L01_INO
#define KYOSHO2_NRF24L01_INO
#define LOLI_NRF24L01_INO
@@ -745,6 +746,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
SKYTMBLR
PROTO_JOYSWAY
NONE
PROTO_KAMTOM
NONE
PROTO_KF606
KF606_KF606
KF606_MIG320

View File

@@ -28,6 +28,7 @@ static void __attribute__((unused)) XN297_SetTXAddr(const uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_SetRXAddr(const uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_SetTxRxMode(enum TXRX_State);
static void __attribute__((unused)) XN297_SendPayload(uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_ReSendPayload();
static void __attribute__((unused)) XN297_WritePayload(uint8_t*, uint8_t);
static void __attribute__((unused)) XN297_WriteEnhancedPayload(uint8_t*, uint8_t, uint8_t);
static bool __attribute__((unused)) XN297_IsRX();

View File

@@ -1981,6 +1981,15 @@ Model: DF-Models SkyTumbler
RTH not supported
## KAMTOM - *104*
Models: KAMTOM KM24xx (KM32xx?), Pinecone SG-24xx
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
ST|TH|UNK1|UNK2|ST_TR|TH_TR|TH_DR
Low batt telemetry is not yet added.
## KYOSHO2 - *93*
Model: TX KT-17, Minium Edge 540, Minium Citabria

View File

@@ -108,7 +108,7 @@ The images below indicate the pin layout and the location of the ground pin on t
|:---:|:---:|:---:|
<img src="images/V2b_ISP.jpeg" width="189" height="200" /> | <img src="images/MPTM_PCB_2.3d_ISP.png" width="486" height="201" /> | <img src="images/ProMini_ISP.png" width="195" height="200" /> |
You are now ready to plug in the USB programmer to the computer. If you are looking for a good working USBasp Windows driver, [use this one](http://www.protostack.com/download/USBasp-win-driver-x86-x64-v3.0.7.zip).
You are now ready to plug in the USB programmer to the computer. If you are looking for a good working USBasp Windows driver, [use this one](https://protostack.com.au/download/USBasp-win-driver-x86-x64-v3.0.7.zip).
### Burn bootloader and set fuses
The bootloader only needs to be burned once, unless you decide to switch from one option to the other (or it is accidentally erased). If you have already burned the bootloader / set the fuses you can skip this step.