diff --git a/src/protocol/protocol.h b/src/protocol/protocol.h index 771f4774ff..27f5f527f9 100644 --- a/src/protocol/protocol.h +++ b/src/protocol/protocol.h @@ -1,6 +1,9 @@ #ifndef PROTODEF #else +#ifdef PROTO_HAS_RADIOLINK_CC2530 +PROTODEF(PROTOCOL_RADIOLINK, RADIOLINK_CC2530, AETRG, RADIOLINK_Cmds, "Radiolink") +#endif #ifdef PROTO_HAS_CYRF6936 PROTODEF(PROTOCOL_DEVO, CYRF6936, EATRG, DEVO_Cmds, "DEVO") PROTODEF(PROTOCOL_WK2801, CYRF6936, EATRG, WK2x01_Cmds, "WK2801") diff --git a/src/protocol/radiolink.c b/src/protocol/radiolink.c new file mode 100644 index 0000000000..c2f3febdbe --- /dev/null +++ b/src/protocol/radiolink.c @@ -0,0 +1,137 @@ +/* + 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. + + Deviation 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 Deviation. If not, see . + */ + +#include "common.h" +#include "interface.h" +#include "mixer.h" +#include "config/model.h" +#include "config/tx.h" +#include "telemetry.h" +#include "protospi.h" + +#ifdef PROTO_HAS_RADIOLINK_CC2530 + +#define PACKET_SIZE 41 +#define PACKET_INTERVAL 4000 + +static u8 packet[PACKET_SIZE]; + +static u16 scale_channel(s32 chanval, s32 inMin, s32 inMax, u16 destMin, u16 destMax) +{ + s32 range = (s32)destMax - (s32)destMin; + s32 chanrange = inMax - inMin; + + if (chanval < inMin) + chanval = inMin; + else if (chanval > inMax) + chanval = inMax; + return (range * (chanval - inMin)) / chanrange + destMin; +} + +static void send_packet() +{ + u8 i = 0; + u8 chan; + u16 val; + packet[i++] = 0xaa; + packet[i++] = 0xaa; + packet[i++] = 0x29; + packet[i++] = 0x01; + // channels + for (chan = 0; chan < 10; chan++) { + // is 0-4000 for 100% endpoints ? can it be extended ? + val = scale_channel(Channels[chan], CHAN_MIN_VALUE, CHAN_MAX_VALUE, 4000, 0); + packet[i++] = val >> 8; + packet[i++] = val & 0xff; + } + // failsafe + for (chan = 0; chan < 8; chan++) { + // any way to disable failsafe on a channel ? (keep last received value) + val = scale_channel(Model.limits[chan].failsafe, -100, 100, 4000, 0); + packet[i++] = val >> 8; + packet[i++] = val & 0xff; + } + // checksum + packet[40] = packet[4]; + for (i = 5; i < PACKET_SIZE-1; i++) + packet[40] += packet[i]; + + // send packet to Radiolink CC2530 module + PROTO_CS_LO(RADIOLINK_CC2530); + for (i = 0; i < PACKET_SIZE; i++) + packet[i] = PROTOSPI_xfer(packet[i]); + PROTO_CS_HI(RADIOLINK_CC2530); + + // todo: packet[] now contains the module's response, with telemetry data +} + +static u16 radiolink_cb() +{ + send_packet(); + return PACKET_INTERVAL; +} + +static void RADIOLINK_Initialize() +{ + PROTO_CS_HI(RADIOLINK_CC2530); + PROTOSPI_pin_clear(RADIOLINK_CC2530_RESET_PIN); + msleep(100); + PROTOSPI_pin_set(RADIOLINK_CC2530_RESET_PIN); +} + +static void RADIOLINK_Stop() +{ + PROTO_CS_HI(RADIOLINK_CC2530); + PROTOSPI_pin_clear(RADIOLINK_CC2530_RESET_PIN); +} + +static int RADIOLINK_Reset() +{ + RADIOLINK_Initialize(); + send_packet(); + RADIOLINK_Stop(); +#ifdef EMULATOR + return 1; +#endif + return (packet[0] == 0x55) && (packet[1] == 0x55); +} + +static void initialize() +{ + CLOCK_StopTimer(); + RADIOLINK_Initialize(); + CLOCK_StartTimer(1000, radiolink_cb); +} + +uintptr_t RADIOLINK_Cmds(enum ProtoCmds cmd) +{ + switch (cmd) { + case PROTOCMD_INIT: initialize(); return 0; + case PROTOCMD_RESET: + case PROTOCMD_DEINIT: + CLOCK_StopTimer(); + return (RADIOLINK_Reset() ? 1 : -1); + case PROTOCMD_CHECK_AUTOBIND: return 1; + case PROTOCMD_BIND: initialize(); return 0; + case PROTOCMD_NUMCHAN: return 10; + case PROTOCMD_DEFAULT_NUMCHAN: return 10; + case PROTOCMD_CHANNELMAP: return AETRG; + case PROTOCMD_TELEMETRYSTATE: return PROTO_TELEM_UNSUPPORTED; + default: break; + } + return 0; +} + +#endif diff --git a/src/target.h b/src/target.h index 0417513976..b98e87223e 100644 --- a/src/target.h +++ b/src/target.h @@ -49,6 +49,7 @@ enum Radio { CC2500, NRF24L01, MULTIMOD, + RADIOLINK_CC2530, R9M, TX_MODULE_LAST, };