just load the code, hit reset, and turn on the rc controller while holding the button

Dependencies:   mbed

Committer:
LukeMar
Date:
Wed Nov 28 20:08:13 2018 +0000
Revision:
0:35253c4bb774
bind code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LukeMar 0:35253c4bb774 1 /*
LukeMar 0:35253c4bb774 2 Spektrum.cpp
LukeMar 0:35253c4bb774 3 Implementation file for Spektrum serial receiver mbed library
LukeMar 0:35253c4bb774 4 Dennis Evangelista, 2018
LukeMar 0:35253c4bb774 5 */
LukeMar 0:35253c4bb774 6
LukeMar 0:35253c4bb774 7 #include "mbed.h"
LukeMar 0:35253c4bb774 8 #include "rtos.h"
LukeMar 0:35253c4bb774 9
LukeMar 0:35253c4bb774 10 #include "Spektrum.h"
LukeMar 0:35253c4bb774 11
LukeMar 0:35253c4bb774 12
LukeMar 0:35253c4bb774 13
LukeMar 0:35253c4bb774 14
LukeMar 0:35253c4bb774 15
LukeMar 0:35253c4bb774 16
LukeMar 0:35253c4bb774 17 /** Spektrum is used for a working connection to a Spektrum Satellite receiver
LukeMar 0:35253c4bb774 18 @param tx orange wire, 3.3V supply pin (should be held high normally)
LukeMar 0:35253c4bb774 19 @param rx gray wire, rx pin from the receiver
LukeMar 0:35253c4bb774 20 The black wire should be connected to ground.
LukeMar 0:35253c4bb774 21 The receiver should first be bound using a BindPlug object.
LukeMar 0:35253c4bb774 22 */
LukeMar 0:35253c4bb774 23 Spektrum::Spektrum(PinName tx, PinName rx):
LukeMar 0:35253c4bb774 24 _rx(tx, rx, SPEKTRUM_BAUD){
LukeMar 0:35253c4bb774 25
LukeMar 0:35253c4bb774 26 // receiver uses e.g. p13, p14 and 115200 baud.
LukeMar 0:35253c4bb774 27 _rx.set_blocking(false); // want receiver to not block
LukeMar 0:35253c4bb774 28 period_ms = 11; // start with 11ms period.
LukeMar 0:35253c4bb774 29
LukeMar 0:35253c4bb774 30 // initialize public variables...
LukeMar 0:35253c4bb774 31 system = 0; // should be 0xa2 or 0xb2 for DSMX modes
LukeMar 0:35253c4bb774 32 fades = 0;
LukeMar 0:35253c4bb774 33 for (int i=0; i<SPEKTRUM_CHANNELS; i++){
LukeMar 0:35253c4bb774 34 channel[i] = 0;
LukeMar 0:35253c4bb774 35 pulsewidth[i] = 0;
LukeMar 0:35253c4bb774 36 }
LukeMar 0:35253c4bb774 37 valid = false;
LukeMar 0:35253c4bb774 38
LukeMar 0:35253c4bb774 39 // start the packet reading thread
LukeMar 0:35253c4bb774 40 _packet_thread.start(callback(this,&Spektrum::_packet_callback));
LukeMar 0:35253c4bb774 41 } // Spektrum(tx, rx) constructor
LukeMar 0:35253c4bb774 42
LukeMar 0:35253c4bb774 43
LukeMar 0:35253c4bb774 44
LukeMar 0:35253c4bb774 45
LukeMar 0:35253c4bb774 46 /** Destructor for Spektrum object
LukeMar 0:35253c4bb774 47 */
LukeMar 0:35253c4bb774 48 Spektrum::~Spektrum(){
LukeMar 0:35253c4bb774 49 } // ~Spektrum() destructor
LukeMar 0:35253c4bb774 50
LukeMar 0:35253c4bb774 51
LukeMar 0:35253c4bb774 52
LukeMar 0:35253c4bb774 53 /** Private callback for when a packet is received
LukeMar 0:35253c4bb774 54 */
LukeMar 0:35253c4bb774 55 void Spektrum::_packet_callback(void){
LukeMar 0:35253c4bb774 56 // local variables
LukeMar 0:35253c4bb774 57 int count; // used to get error code -11 or num of bytes _rx.read()
LukeMar 0:35253c4bb774 58 uint64_t now; // for getting 11 or 22 ms period via ThisThread::sleep_until()
LukeMar 0:35253c4bb774 59 unsigned int i; // counter for for loop
LukeMar 0:35253c4bb774 60 unsigned int data; // for assembling 2 bytes into uint16_t
LukeMar 0:35253c4bb774 61 unsigned int chanid; // for decoding channel ID with mask 0x7800
LukeMar 0:35253c4bb774 62 unsigned int servopos; // for decoding servo value with mask 0x07ff
LukeMar 0:35253c4bb774 63
LukeMar 0:35253c4bb774 64 // setup
LukeMar 0:35253c4bb774 65 debug("Spektrum::_packet_thread started\r\n");
LukeMar 0:35253c4bb774 66
LukeMar 0:35253c4bb774 67 // loop
LukeMar 0:35253c4bb774 68 _rx.sync(); // flush buffer
LukeMar 0:35253c4bb774 69 while(1){
LukeMar 0:35253c4bb774 70 now = rtos::Kernel::get_ms_count(); // for timing
LukeMar 0:35253c4bb774 71 count = _rx.read(_buf,SPEKTRUM_PACKET_SIZE); // try to read packet
LukeMar 0:35253c4bb774 72
LukeMar 0:35253c4bb774 73 if (count == SPEKTRUM_PACKET_SIZE){
LukeMar 0:35253c4bb774 74 // got a full sized packet
LukeMar 0:35253c4bb774 75 if (_buf[1] == SPEKTRUM_22MS_2048_DSMX){
LukeMar 0:35253c4bb774 76 period_ms = 22;
LukeMar 0:35253c4bb774 77 valid = true;
LukeMar 0:35253c4bb774 78 } // got 22ms packets
LukeMar 0:35253c4bb774 79 else if (_buf[1] == SPEKTRUM_11MS_2048_DSMX){
LukeMar 0:35253c4bb774 80 period_ms = 11;
LukeMar 0:35253c4bb774 81 valid = true;
LukeMar 0:35253c4bb774 82 } // got 11ms packets
LukeMar 0:35253c4bb774 83 else
LukeMar 0:35253c4bb774 84 // if system is not 0xa2 or 0xb2, treat as invalid
LukeMar 0:35253c4bb774 85 valid = false;
LukeMar 0:35253c4bb774 86 } // if count == 16
LukeMar 0:35253c4bb774 87 else {
LukeMar 0:35253c4bb774 88 // count wasn't 16 so some kind of error
LukeMar 0:35253c4bb774 89 valid = false;
LukeMar 0:35253c4bb774 90 _rx.sync(); // not getting enough bytes, so sync()
LukeMar 0:35253c4bb774 91 }
LukeMar 0:35253c4bb774 92
LukeMar 0:35253c4bb774 93 if (valid){
LukeMar 0:35253c4bb774 94 // got a valid packet so parse it
LukeMar 0:35253c4bb774 95 fades = _buf[0];
LukeMar 0:35253c4bb774 96 system = _buf[1];
LukeMar 0:35253c4bb774 97 for (i=0; i<SPEKTRUM_SERVOS; i++){
LukeMar 0:35253c4bb774 98 data = (_buf[2*i+2]<<8) | _buf[2*i+2+1];
LukeMar 0:35253c4bb774 99 chanid = (data & SPEKTRUM_MASK_2048_CHANID) >> 11;
LukeMar 0:35253c4bb774 100 servopos = data & SPEKTRUM_MASK_2048_SXPOS;
LukeMar 0:35253c4bb774 101 channel[chanid] = servopos;
LukeMar 0:35253c4bb774 102 pulsewidth[chanid] = SPEKTRUM_COUNT2US(servopos);
LukeMar 0:35253c4bb774 103 } // for each servo in packet
LukeMar 0:35253c4bb774 104 } // if(valid)
LukeMar 0:35253c4bb774 105
LukeMar 0:35253c4bb774 106 ThisThread::sleep_until(now+period_ms); // sleep to get right rate
LukeMar 0:35253c4bb774 107 } // while(1)
LukeMar 0:35253c4bb774 108 } // _packet_callback()
LukeMar 0:35253c4bb774 109
LukeMar 0:35253c4bb774 110
LukeMar 0:35253c4bb774 111
LukeMar 0:35253c4bb774 112
LukeMar 0:35253c4bb774 113
LukeMar 0:35253c4bb774 114
LukeMar 0:35253c4bb774 115
LukeMar 0:35253c4bb774 116
LukeMar 0:35253c4bb774 117
LukeMar 0:35253c4bb774 118 /** BindPlug is used to bind a Spektrum Satellite receiver
LukeMar 0:35253c4bb774 119 @param tx orange wire, 3.3V supply pin, here used as a DigitalOut
LukeMar 0:35253c4bb774 120 @param rx gray wire, rx pin, here used as a DigitalOut
LukeMar 0:35253c4bb774 121 @param mode is mode, e.g. internal or external, DSM2 or DSMX, 11 or 22ms
LukeMar 0:35253c4bb774 122 The black wire should be connected to ground.
LukeMar 0:35253c4bb774 123 Default mode is internal, DSMX, 11 ms. Once created, this object will
LukeMar 0:35253c4bb774 124 send a number of falling pulses over the 3.3V supply pin to trigger
LukeMar 0:35253c4bb774 125 the satellite receiver to go into bind mode.
LukeMar 0:35253c4bb774 126 */
LukeMar 0:35253c4bb774 127 BindPlug::BindPlug(PinName tx, PinName rx, int mode): _3Vpin(tx),_datapin(rx){
LukeMar 0:35253c4bb774 128 int i; // counter
LukeMar 0:35253c4bb774 129
LukeMar 0:35253c4bb774 130 // within 200 ms of applying power, supply a bunch of falling pulses
LukeMar 0:35253c4bb774 131 // according to table in Spektrum docs, most likely 9 pulses for
LukeMar 0:35253c4bb774 132 // internal mode, DSMX, 11 ms.
LukeMar 0:35253c4bb774 133 _3Vpin = 0;
LukeMar 0:35253c4bb774 134 _datapin = 0;
LukeMar 0:35253c4bb774 135 wait(1);
LukeMar 0:35253c4bb774 136 _3Vpin = 1;
LukeMar 0:35253c4bb774 137 _datapin = 1;
LukeMar 0:35253c4bb774 138 wait_ms(72);
LukeMar 0:35253c4bb774 139 debug("pulse ");
LukeMar 0:35253c4bb774 140 for(i=0; i<mode; i++){
LukeMar 0:35253c4bb774 141 debug("%d ",i);
LukeMar 0:35253c4bb774 142 wait_us(116);
LukeMar 0:35253c4bb774 143 _datapin = 0; // this is the falling pulse
LukeMar 0:35253c4bb774 144 wait_us(116);
LukeMar 0:35253c4bb774 145 _datapin = 1;
LukeMar 0:35253c4bb774 146 }
LukeMar 0:35253c4bb774 147 debug("\r\n");
LukeMar 0:35253c4bb774 148 } // BindPlug(bind, mode) constructor
LukeMar 0:35253c4bb774 149
LukeMar 0:35253c4bb774 150 /** Destructor for BindPlug object
LukeMar 0:35253c4bb774 151 */
LukeMar 0:35253c4bb774 152 BindPlug::~BindPlug(){
LukeMar 0:35253c4bb774 153 } // ~BindPlug() destructor
LukeMar 0:35253c4bb774 154
LukeMar 0:35253c4bb774 155
LukeMar 0:35253c4bb774 156
LukeMar 0:35253c4bb774 157
LukeMar 0:35253c4bb774 158
LukeMar 0:35253c4bb774 159
LukeMar 0:35253c4bb774 160 /* LATER
LukeMar 0:35253c4bb774 161 SpektrumTestDevice::SpektrumTestDevice(PinName tx, PinName rx): _receiver(tx,rx){
LukeMar 0:35253c4bb774 162 _receiver.baud(SPEKTRUM_BAUD);
LukeMar 0:35253c4bb774 163 } // SpektrumTestDevice(tx, rx) constructor
LukeMar 0:35253c4bb774 164 SpektrumTestDevice::~SpektrumTestDevice(){
LukeMar 0:35253c4bb774 165 } // ~SpektrumTestDevice() destructor
LukeMar 0:35253c4bb774 166 */