├── keywords.txt ├── examples ├── ManchesterTX_Byte │ └── ManchesterTX_Byte.ino ├── ManchesterRX_Byte │ └── ManchesterRX_Byte.ino ├── ManchesterTX_Array │ └── ManchesterTX_Array.ino └── ManchesterRX_Array │ └── ManchesterRX_Array.ino ├── README.markdown ├── ManchesterRF.h └── ManchesterRF.cpp /keywords.txt: -------------------------------------------------------------------------------- 1 | man LITERAL1 2 | Manchester KEYWORD1 3 | ManchesterRF KEYWORD1 4 | setTxPin KEYWORD2 5 | setRxPin KEYWORD2 6 | beginReceive KEYWORD2 7 | beginReceiveBytes KEYWORD2 8 | receiveComplete KEYWORD2 9 | getMessage KEYWORD2 10 | stopReceive KEYWORD2 11 | 12 | isDataAvailable KEYWORD2 13 | 14 | transmitArray KEYWORD2 15 | receiveArray KEYWORD2 16 | transmitPacket KEYWORD2 17 | receivePacket KEYWORD2 18 | transmitByte KEYWORD2 19 | receiveByte KEYWORD2 20 | transmitWord KEYWORD2 21 | receiveWord KEYWORD2 22 | 23 | TxInit KEYWORD2 24 | RxInit KEYWORD2 25 | 26 | setBalance KEYWORD2 27 | 28 | -------------------------------------------------------------------------------- /examples/ManchesterTX_Byte/ManchesterTX_Byte.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Manchester Receiver example 4 | 5 | In this example transmitter will transmit two 8 bit numbers per transmittion 6 | 7 | */ 8 | 9 | 10 | #include "ManchesterRF.h" //https://github.com/cano64/ManchesterRF 11 | 12 | 13 | 14 | #define TX_PIN 3 //any pin can transmit 15 | #define LED_PIN 13 16 | 17 | ManchesterRF rf(MAN_4800); //link speed, try also MAN_300, MAN_600, MAN_1200, MAN_2400, MAN_4800, MAN_9600, MAN_19200, MAN_38400 18 | 19 | uint8_t data = 0; 20 | 21 | void setup() { 22 | pinMode(LED_PIN, OUTPUT); 23 | digitalWrite(LED_PIN, HIGH); 24 | rf.TXInit(TX_PIN); 25 | } 26 | 27 | void loop() { 28 | 29 | rf.transmitByte(++data, data*data); 30 | digitalWrite(LED_PIN, digitalRead(LED_PIN)); //blink the LED on receive 31 | delay(100); 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /examples/ManchesterRX_Byte/ManchesterRX_Byte.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Manchester Receiver example 4 | 5 | In this example receiver will receive two 8 bit numbers per transmittion 6 | 7 | */ 8 | 9 | 10 | #include "ManchesterRF.h" //https://github.com/cano64/ManchesterRF 11 | 12 | 13 | 14 | #define RX_PIN 4 //any pin can receive 15 | #define LED_PIN 13 16 | 17 | ManchesterRF rf(MAN_4800); //link speed, try also MAN_300, MAN_600, MAN_1200, MAN_2400, MAN_4800, MAN_9600, MAN_19200, MAN_38400 18 | 19 | uint8_t a, b; 20 | 21 | void setup() { 22 | pinMode(LED_PIN, OUTPUT); 23 | digitalWrite(LED_PIN, HIGH); 24 | rf.RXInit(RX_PIN); 25 | } 26 | 27 | void loop() { 28 | 29 | if (rf.available()) { //something is in RX buffer 30 | if (rf.receiveByte(a, b)) { 31 | //process the data 32 | //... 33 | digitalWrite(LED_PIN, digitalRead(LED_PIN)); //blink the LED on receive 34 | } 35 | } 36 | 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /examples/ManchesterTX_Array/ManchesterTX_Array.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Manchester Receiver example 4 | 5 | In this example transmitter will transmit an array of 8 bit numbers per transmittion 6 | 7 | */ 8 | 9 | 10 | #include "ManchesterRF.h" //https://github.com/cano64/ManchesterRF 11 | 12 | 13 | 14 | #define TX_PIN 3 //any pin can transmit 15 | #define LED_PIN 13 16 | 17 | ManchesterRF rf(MAN_4800); //link speed, try also MAN_300, MAN_600, MAN_1200, MAN_2400, MAN_4800, MAN_9600, MAN_19200, MAN_38400 18 | 19 | #define asize 8 20 | uint8_t data[asize]; 21 | 22 | void setup() { 23 | pinMode(LED_PIN, OUTPUT); 24 | digitalWrite(LED_PIN, HIGH); 25 | rf.TXInit(TX_PIN); 26 | } 27 | 28 | void loop() { 29 | 30 | for (int i = 0; i < asize; i++) { 31 | data[i] = i * i; 32 | rf.transmitArray(asize, data); 33 | } 34 | digitalWrite(LED_PIN, digitalRead(LED_PIN)); //blink the LED on receive 35 | 36 | delay(100); 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /examples/ManchesterRX_Array/ManchesterRX_Array.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Manchester Receiver example 4 | 5 | In this example receiver will receive an array of 8 bit numbers per transmittion 6 | 7 | */ 8 | 9 | 10 | #include "ManchesterRF.h" //https://github.com/cano64/ManchesterRF 11 | 12 | 13 | 14 | #define RX_PIN 4 //any pin can receive 15 | #define LED_PIN 13 16 | 17 | ManchesterRF rf(MAN_4800); //link speed, try also MAN_300, MAN_600, MAN_1200, MAN_2400, MAN_4800, MAN_9600, MAN_19200, MAN_38400 18 | 19 | uint8_t size; 20 | uint8_t *data; 21 | 22 | void setup() { 23 | pinMode(LED_PIN, OUTPUT); 24 | digitalWrite(LED_PIN, HIGH); 25 | rf.RXInit(RX_PIN); 26 | } 27 | 28 | void loop() { 29 | 30 | if (rf.available()) { //something is in RX buffer 31 | if (rf.receiveArray(size, &data)) { 32 | //process the data 33 | for (int i = 0; i < size; i++) { 34 | data[i]; //do something with the data 35 | } 36 | digitalWrite(LED_PIN, digitalRead(LED_PIN)); //blink the LED on receive 37 | } 38 | } 39 | 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | This is a [Manchester encoding](http://en.wikipedia.org/wiki/Manchester_code) RF library which works on Arduino and ATTiny. 2 | 3 | Library supports: 4 | 5 | various microcontrollers 6 | * ATmega1284 7 | * ATmega328 8 | * ATmega8 9 | * ATMega32U4 10 | * ATtiny84 (44, 24) 11 | * ATtiny85 (45, 85) 12 | 13 | Various microcontroller's speed both RX and TX 14 | All microcontroller speeds between 1Mhz and 20Mhz are supported. 15 | The library has been tested with the following common speeds: 16 | * 1Mhz 17 | * 8Mhz 18 | * 16Mhz 19 | 20 | Various transmission speeds, the maximum transmition speed is mostly dependent on your microcontroller speed 21 | * 300baud 22 | * 600baud 23 | * 1200baud 24 | * 2400baud 25 | * 4800baud 26 | * 9600baud 27 | * 19200baud 28 | 29 | With this library you can sucessfully transmit data between various microcontrollers 30 | runnning at various speeds even if their clock speed drifts up to 100%. 31 | It's specifically designed to work with innacurate internal oscilator. 32 | 33 | Speed 34 | ------ 35 | Transmition speed is determined by the speed of the microcontroller. 36 | Following speeds can be achieved using direct port manipulation. 37 | Receiver: 38 | freq -> max receive speed 39 | 1Mhz -> 1200baud 40 | 8Mhz -> 9600baud 41 | 16Mhz -> 19200baud 42 | 43 | Preserving PWM 44 | ------ 45 | Although this library is using timers, PWM functionality related to that timer will be preserved, 46 | PWM frequency will increase though. Timer prescaler will be set to 1 (no prescaler) and therefore PWM frequency will be 47 | F_CPU/256. 48 | 49 | 50 | Direct port manipulation 51 | ------ 52 | Standard Arduino digitalRead() and digitalWrite() functions are extremely slow. 53 | For faster comminication it is necessary to use direct port manipulation. 54 | 55 | 56 | 57 | 58 | Notes about transmitters 59 | ------ 60 | 61 | http://blog.solidremote.com/post/rf-module-external-antenna-design.aspx 62 | 63 | 64 | The library has been tested with common 315Mhz and 433Mhz transmitters using ASK OOK. 65 | Tips to improve your transmit distance: 66 | Attaching an antenna will greatly improve transmit distance (from few cm to few m) 67 | for 315Mhz use 23.81 cm straight wire, for 433Mhz use 17.28cm straight wire as antenna. 68 | If possible keep the wire straight, away from ground wire, and away from the rest of the circuit 69 | and battery pack. 70 | Transmitter can use anything from 3.3V to 12V. Increasing voltage will increase transmit 71 | distance. If you are using voltage regulator, attach transmitter directly to the battery. 72 | Receiver needs 5V, it doesn't work on 3.3V 73 | 74 | Speed: I was able to achieve 19200 bauds between two 16Mhz Arduinos, 75 | or 2400 bauds between two 1Mhz ATTiny85, you can try different speeds to see which works 76 | the best for you. 77 | 78 | Full duplex: for bidirectional communication use both 315Mhz and 433Mhz transmitters. 79 | This way they can transmit at the same time without interfering with each other. If you have 80 | just one type, wait for receiver to finish receiving before transmitting. 81 | 82 | Credits 83 | ------ 84 | 85 | * Library originally from [carl47](http://arduino.cc/forum/index.php?action=profile;u=14566) on 86 | [this thread](http://arduino.cc/forum/index.php/topic,63755.0.html) 87 | * Contributions from [mchr3k](http://mchr3k-arduino.blogspot.com/), 88 | [Mike](https://github.com/MichaelBell/Arduino-sketches) 89 | [Cano](https://github.com/cano64) 90 | -------------------------------------------------------------------------------- /ManchesterRF.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 4 | https://github.com/mchr3k/arduino-libs-manchester 5 | 6 | 7 | 8 | This code is based on the Atmel Corporation Manchester 9 | Coding Basics Application Note. 10 | 11 | http://www.atmel.com/dyn/resources/prod_documents/doc9164.pdf 12 | 13 | Quotes from the application note: 14 | 15 | "Manchester coding states that there will always be a transition of the message signal 16 | at the mid-point of the data bit frame. 17 | What occurs at the bit edges depends on the state of the previous bit frame and 18 | does not always produce a transition. A logical '1' is defined as a mid-point transition 19 | from low to high and a '0' is a mid-point transition from high to low. 20 | 21 | We use Timing Based Manchester Decode. 22 | In this approach we will capture the time between each transition coming from the demodulation 23 | circuit." 24 | 25 | Timer 2 is used with a ATMega328. Timer 1 is used for a ATtiny85 and ATtiny84 26 | 27 | This code gives a basic data rate as 1200 bauds. In manchester encoding we send 1 0 for a data bit 0. 28 | We send 0 1 for a data bit 1. This ensures an average over time of a fixed DC level in the TX/RX. 29 | This is required by the ASK RF link system to ensure its correct operation. 30 | The data rate is then 600 bits/s. Higher and lower rates are also supported. 31 | */ 32 | 33 | #ifndef MANCHESTERRF_h 34 | #define MANCHESTERRF_h 35 | 36 | //timer scaling factors for different transmission speeds 37 | #define MAN_300 0 38 | #define MAN_600 1 39 | #define MAN_1200 2 40 | #define MAN_2400 3 41 | #define MAN_4800 4 42 | #define MAN_9600 5 43 | #define MAN_19200 6 44 | #define MAN_38400 7 45 | 46 | /* 47 | Timer 2 in the ATMega328 and Timer 1 in a ATtiny85 is used to find the time between 48 | each transition coming from the demodulation circuit. 49 | Their setup is for sampling the input in regular intervals. 50 | For practical reasons we use power of 2 timer prescaller for sampling, 51 | for best timing we use pulse lenght as integer multiple of sampling speed. 52 | We chose to sample every 8 ticks, and pulse lenght of 48 ticks 53 | thats 6 samples per pulse, lower sampling rate (3) will not work well for 54 | innacurate clocks (like internal oscilator) higher sampling rate (12) will 55 | cause too much overhead and will not work at higher transmission speeds. 56 | This gives us 16000000Hz/48/256 = 1302 pulses per second (so it's not really 1200) 57 | At different transmission speeds or on different microcontroller frequencies, clock prescaller is adjusted 58 | to be compatible with those values. We allow about 50% clock speed difference both ways 59 | allowing us to transmit even with up to 100% in clock speed difference 60 | */ 61 | 62 | 63 | /* 64 | Signal timing, we take sample every 8 clock ticks 65 | 66 | ticks: [0]-[8]--[16]-[24]-[32]-[40]-[48]-[56]-[64]-[72]-[80]-[88]-[96][104][112][120][128][136] 67 | samples: |----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----| 68 | single: | [--------|----------] 69 | double: | [-----------------|--------------------] 70 | signal: |_____________________________ ______________________ 71 | | |_____________________________| 72 | 73 | */ 74 | 75 | 76 | //setup timing for receiver 77 | #define MinCount 31 //33 //pulse lower count limit on capture 78 | #define MaxCount 65 //pulse higher count limit on capture 79 | #define MinLongCount 66 //pulse lower count on double pulse 80 | #define MaxLongCount 129 //pulse higher count on double pulse 81 | 82 | //setup timing for transmitter 83 | #define HALF_BIT_INTERVAL 3072U //(=48 * 1024 * 1000000 / 16000000Hz) microseconds for speed factor 0 (300baud) 84 | 85 | //it's common to zero terminate a string or to transmit small numbers involving a lot of leading zeroes 86 | //those zeroes may be mistaken for training pattern, confusing the receiver and resulting high packet lost, 87 | //therefore we xor the data with random decoupling mask 88 | #define DECOUPLING_MASK 0b11001010 89 | 90 | #define RX_MODE_PRE 0 91 | #define RX_MODE_SYNC 1 92 | #define RX_MODE_DATA 2 93 | #define RX_MODE_MSG 3 94 | #define RX_MODE_IDLE 4 95 | 96 | #define TimeOutDefault -1 //the timeout in msec default blocks 97 | 98 | #if defined(ARDUINO) && ARDUINO >= 100 99 | #include "Arduino.h" 100 | #else 101 | #include "WProgram.h" 102 | #include 103 | #endif 104 | 105 | class ManchesterRF : public Stream { 106 | public: 107 | ManchesterRF(uint8_t SF = MAN_4800); //the constructor 108 | 109 | void setBalance(int8_t bf); 110 | 111 | void TXInit(); 112 | void TXInit(uint8_t pin); //set pin 113 | void TXInit(uint8_t port, uint8_t mask); //set port and mask 114 | // void TxInit(uint8_t pin, int8_t bf); //set pin and balance factor 115 | //void TxInit(uint8_t port, uint8_t mask, int8_t bf); //set port and mask and balance factor 116 | 117 | void RXInit(); 118 | void RXInit(uint8_t pin); //set pin 119 | void RXInit(uint8_t port, uint8_t mask); //set port and mask 120 | 121 | void setDebugPortMask(uint8_t port, uint8_t mask); 122 | 123 | //void setup(uint8_t Tpin, uint8_t Rpin); //set up receiver 124 | 125 | // void transmit(uint16_t data); //transmit 16 bits of data 126 | 127 | //uint8_t decodeMessage(uint16_t m, uint8_t &id, uint8_t &data); //decode 8 bit payload and 4 bit ID from the message, return 1 of checksum is correct, otherwise 0 128 | //uint16_t encodeMessage(uint8_t id, uint8_t data); //encode 8 bit payload, 4 bit ID and 4 bit checksum into 16 bit 129 | 130 | // uint8_t available(); 131 | 132 | uint8_t transmitArray(uint8_t size, uint8_t *data); // transmit array of bytes 133 | uint8_t receiveArray(uint8_t &size, uint8_t **data); // receive array of bytes 134 | 135 | uint8_t transmitPacket(uint8_t size, uint8_t from, uint8_t to, uint8_t meta, uint8_t *payload); //decode receive buffer into a packet, return 1 if valid packet received, otherwise 0 136 | uint8_t receivePacket(uint8_t &size, uint8_t &from, uint8_t &to, uint8_t &meta, uint8_t **payload); //decode receive buffer into a packet, return 1 if valid packet received, otherwise 0 137 | 138 | uint8_t transmitByte(uint8_t data); 139 | uint8_t receiveByte(uint8_t &data); 140 | 141 | uint8_t transmitByte(uint8_t data0, uint8_t data1); 142 | uint8_t receiveByte(uint8_t &data0, uint8_t &data1); 143 | 144 | uint8_t transmitByte(uint8_t data0, uint8_t data1, uint8_t data2); 145 | uint8_t receiveByte(uint8_t &data0, uint8_t &data1, uint8_t &data2); 146 | 147 | 148 | 149 | uint8_t transmitWord(uint16_t data); 150 | uint8_t receiveWord(uint16_t &data); 151 | 152 | //wrappers for global functions 153 | void beginReceive(void); 154 | // void beginReceiveArray(uint8_t maxBytes, uint8_t *data); 155 | // uint8_t receiveComplete(void); 156 | // uint16_t getMessage(void); 157 | void stopReceive(void); 158 | 159 | uint8_t speedFactor; 160 | uint16_t delay10; 161 | uint16_t delay20; 162 | uint16_t delay11; 163 | uint16_t delay21; 164 | 165 | virtual size_t write(uint8_t); 166 | virtual int available(void); 167 | virtual int peek(void); 168 | virtual int read(void); 169 | virtual void flush(void); 170 | using Print::write; 171 | 172 | 173 | private: 174 | void pin2PortMask(uint8_t pin, uint8_t &port, uint8_t &mask); 175 | void sendZero(void); 176 | void sendOne(void); 177 | uint8_t TxPin; 178 | uint8_t directTxMask; 179 | uint8_t directTxPort; 180 | int8_t balanceFactor; 181 | };//end of class ManchesterRF 182 | 183 | // Cant really do this as a real C++ class, since we need to have 184 | // an ISR 185 | extern "C" 186 | { 187 | 188 | //begin the timer used to receive data 189 | extern void MANRX_SetupReceive(uint8_t speedFactor = MAN_4800); 190 | 191 | // begin receiving 16 bits 192 | extern void MANRX_BeginReceive(void); 193 | 194 | // begin receiving a byte array 195 | extern void MANRX_BeginReceiveBytes(uint8_t maxBytes, uint8_t *data); 196 | 197 | // stop receiving data 198 | extern void MANRX_StopReceive(void); 199 | 200 | //extern void MAN_RX_INTERRUPT_HANDLER(); 201 | } 202 | 203 | 204 | #endif 205 | -------------------------------------------------------------------------------- /ManchesterRF.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This code is based on the Atmel Corporation Manchester 3 | Coding Basics Application Note. 4 | 5 | http://www.atmel.com/dyn/resources/prod_documents/doc9164.pdf 6 | 7 | Quotes from the application note: 8 | 9 | "Manchester coding states that there will always be a transition of the message signal 10 | at the mid-point of the data bit frame. 11 | What occurs at the bit edges depends on the state of the previous bit frame and 12 | does not always produce a transition. A logical '1' is defined as a mid-point transition 13 | from low to high and a '0' is a mid-point transition from high to low. 14 | 15 | We use Timing Based Manchester Decode. 16 | In this approach we will capture the time between each transition coming from the demodulation 17 | circuit." 18 | 19 | Timer 2 is used with a ATMega328. Timer 1 is used for a ATtiny85. 20 | 21 | This code gives a basic data rate as 1200 bauds. In manchester encoding we send 1 0 for a data bit 0. 22 | We send 0 1 for a data bit 1. This ensures an average over time of a fixed DC level in the TX/RX. 23 | This is required by the ASK RF link system to ensure its correct operation. 24 | The data rate is then 600 bits/s. 25 | */ 26 | 27 | #include "ManchesterRF.h" 28 | 29 | #define MDEBUG 1 30 | 31 | 32 | /* 33 | message is an array of bytes received by receiver in one burst 34 | structure of an message array, size is a number of bytes received 35 | [size][data][data]...[data][undefined][undefined] ...[undefined] 36 | [ 0 ][ 1 ][ 2 ]...[size][ size + 1][ size + 2] ...[MAN_MESSAGE_SIZE-1] 37 | 38 | 39 | receive buffer consist of a ring buffer of messages 40 | [ 0 ][ 1 ][ 2 ][ 3 ]...[MAN_BUF_SIZE-1] 41 | [message][message][message][message]...[message] 42 | ^ ^ ^ 43 | working -----+ | | place where client will read current message content from 44 | | | 45 | man_rx_buff_start ----+ | place of the next message, isDataAvailable() will look there 46 | | 47 | man_rx_buff_end -----+ place where the new message is being received 48 | 49 | 50 | The circular buffer is implemented with one slot open, that slot is read from the main program 51 | 52 | */ 53 | 54 | // MAN_BUF_SIZE must be 2 or more based on available microcontroller memory 55 | 56 | #define MAN_MESSAGE_SIZE 16 57 | #if defined( __AVR_ATtinyX5__ ) 58 | #define MAN_BUF_SIZE 2 59 | #elif defined( __AVR_ATtinyX4__ ) 60 | #define MAN_BUF_SIZE 2 61 | #elif defined( __AVR_ATmega328P__ ) 62 | #define MAN_BUF_SIZE 4 63 | #elif defined( __AVR_ATmega1284P__ ) 64 | #define MAN_BUF_SIZE 8 65 | #else 66 | #define MAN_BUF_SIZE 4 67 | #endif 68 | 69 | #define MAN_IS_BUFF_EMPTY (::man_rx_buff_end == ::man_rx_buff_start) 70 | #define MAN_IS_BUFF_FULL ((::man_rx_buff_end+1) % MAN_BUF_SIZE == ::man_rx_buff_start) 71 | 72 | //#define MAN_ADD_TO_CHECKSUM(sum, data) ((uint8_t(sum*sum)) ^ data) 73 | 74 | uint8_t man_rx_buff[MAN_BUF_SIZE][MAN_MESSAGE_SIZE]; 75 | volatile uint8_t man_rx_buff_start = 0; 76 | volatile uint8_t man_rx_buff_end = 0; 77 | 78 | uint8_t man_tx_buff[MAN_MESSAGE_SIZE]; 79 | 80 | static uint8_t RxPin = 255; 81 | static uint8_t directRxPort = 0x00; 82 | static uint8_t directRxMask = 0x00; 83 | 84 | static uint8_t directDebugPort = 0x00; 85 | static uint8_t directDebugMask = 0x00; 86 | 87 | static uint8_t rx_sample = 0; 88 | static uint8_t rx_last_sample = 0; 89 | static uint8_t rx_pulse_width = 0; 90 | static uint8_t rx_pulse_width_inc = 8; 91 | static uint8_t rx_sync_count = 0; 92 | static uint8_t rx_mode = RX_MODE_IDLE; 93 | 94 | static uint16_t rx_manBits = 0; //the received manchester 32 bits 95 | static uint8_t rx_numMB = 0; //the number of received manchester bits 96 | static uint8_t rx_curByte = 0; 97 | 98 | //static uint8_t rx_maxBytes = 2; 99 | //static uint8_t rx_default_data[2]; 100 | //static uint8_t* rx_data = rx_default_data; 101 | 102 | uint8_t sranie[256]; 103 | uint8_t isranie = 0; 104 | 105 | 106 | 107 | //global functions 108 | 109 | //calculates integer logarithm base 2 110 | uint8_t MAN_log2(uint8_t a) { 111 | uint8_t r = 0; 112 | while (a >>= 1) r++; 113 | return r; 114 | } 115 | 116 | 117 | inline void DEBUG_TOGGLE() { 118 | #if defined (MDEBUG) 119 | if (::directDebugPort && ::directDebugMask) { //use direct port manipulation (much faster) 120 | //toggle pin 121 | switch(::directDebugPort) { 122 | #if defined(PINA) 123 | case 1: PINA |= ::directDebugMask; break; 124 | #endif 125 | #if defined(PINB) 126 | case 2: PINB |= ::directDebugMask; break; 127 | #endif 128 | #if defined(PINC) 129 | case 3: PINC |= ::directDebugMask; break; 130 | #endif 131 | #if defined(PIND) 132 | case 4: PIND |= ::directDebugMask; break; 133 | #endif 134 | default:; 135 | } 136 | } 137 | #endif 138 | } 139 | 140 | ManchesterRF::ManchesterRF(uint8_t SF) : 141 | speedFactor(SF), 142 | delay10(0), 143 | delay20(0), 144 | delay11(0), 145 | delay21(0), 146 | TxPin(0), 147 | directTxMask(0), 148 | directTxPort(0), 149 | balanceFactor(0) 150 | { 151 | //debug 152 | //pinMode(7, OUTPUT); 153 | } 154 | 155 | void ManchesterRF::pin2PortMask(uint8_t pin, uint8_t &port, uint8_t &mask) { 156 | mask = 0; 157 | port = 0; 158 | #if defined( __AVR_ATtinyX5__ ) 159 | if (pin < 8) { 160 | mask = _BV(pin); 161 | port = 2; 162 | } 163 | #elif defined( __AVR_ATtinyX4__ ) 164 | if (pin <= 10 && pin >= 3) { 165 | mask = _BV(10 - pin); 166 | port = 1; 167 | } else if (pin < 3) { 168 | mask = _BV(pin); 169 | port = 2; 170 | } 171 | #elif defined( __AVR_ATmega328P__ ) 172 | if (pin < 8) { 173 | mask = _BV(pin); 174 | port = 4; 175 | } else if (pin <= 13) { 176 | mask = _BV(pin - 8); 177 | port = 2; 178 | } else { 179 | mask = _BV(pin - A0); 180 | port = 3; 181 | } 182 | #elif defined( __AVR_ATmega1284P__ ) 183 | if (pin < 8) { 184 | mask = _BV(pin); 185 | } 186 | #endif 187 | } 188 | 189 | /************************** TRANSMIT INIT ****************************/ 190 | 191 | void ManchesterRF::setBalance(int8_t bf) { 192 | this->balanceFactor = bf; 193 | } 194 | 195 | void ManchesterRF::TXInit() { 196 | 197 | // balanceFactor = bf; 198 | // speedFactor = SF; 199 | 200 | //emprirically determined values to compensate for the time loss in overhead 201 | 202 | #if F_CPU < 8000000UL 203 | uint16_t compensationFactor = 48; //24;//40; 204 | #elif F_CPU < 16000000UL 205 | uint16_t compensationFactor = 6; 206 | #else //16000000Mhz 207 | uint16_t compensationFactor = 0; 208 | #endif 209 | 210 | #if F_CPU < 8000000UL 211 | uint16_t compensationFactor2 = 0; 212 | #elif F_CPU < 16000000UL 213 | uint16_t compensationFactor2 = 0; 214 | #else //16000000Mhz 215 | uint16_t compensationFactor2 = 0; 216 | #endif 217 | 218 | /* 219 | Base delay | speed factor 220 | 3072 - 0 221 | 1536 - 1 222 | 768 - 2 223 | 384 - 3 224 | 192 - 4 225 | 96 - 5 226 | 48 - 6 227 | 24 - 7 228 | 12 - 8 229 | 230 | */ 231 | 232 | //this must be signed int 233 | int temp10 = (HALF_BIT_INTERVAL >> speedFactor) - compensationFactor + balanceFactor; 234 | int temp11 = (HALF_BIT_INTERVAL >> speedFactor) - compensationFactor - balanceFactor; 235 | 236 | int temp20 = (HALF_BIT_INTERVAL >> speedFactor) - compensationFactor2 + balanceFactor; 237 | int temp21 = (HALF_BIT_INTERVAL >> speedFactor) - compensationFactor2 - balanceFactor; 238 | 239 | if (temp10 < 0) { 240 | temp21 += temp10; //borrow from second delay to maintain constant speed 241 | temp10 = 0; 242 | } 243 | 244 | if (temp11 < 0) { 245 | temp20 += temp11; //borrow from second delay to maintain constant speed 246 | temp11 = 0; 247 | } 248 | 249 | if (temp21 < 0) temp21 = 0; //too slow for such speed 250 | if (temp20 < 0) temp20 = 0; //too slow for such speed 251 | 252 | delay10 = temp10; 253 | delay11 = temp11; 254 | delay20 = temp20; 255 | delay21 = temp21; 256 | 257 | 258 | // if ((HALF_BIT_INTERVAL >> speedFactor) <= compensationFactor) delay1 = 0; //oops, we are too slow for such speeds 259 | // else delay1 = (HALF_BIT_INTERVAL >> speedFactor) - compensationFactor; 260 | // delay2 = (HALF_BIT_INTERVAL >> speedFactor); // - 2; 261 | 262 | 263 | //delay1 = delay2 = (HALF_BIT_INTERVAL >> speedFactor); 264 | } 265 | 266 | 267 | void ManchesterRF::TXInit(uint8_t pin) { 268 | this->TxPin = pin; 269 | pinMode(pin, OUTPUT); 270 | digitalWrite(pin, LOW); 271 | this->pin2PortMask(pin, this->directTxPort, this->directTxMask); 272 | this->TXInit(); 273 | } 274 | 275 | 276 | void ManchesterRF::TXInit(uint8_t port, uint8_t mask) { 277 | //set pin as output and low 278 | switch(port) { 279 | #if defined(PORTA) 280 | case 1: DDRA |= mask; PORTA &= ~mask; break; 281 | #endif 282 | #if defined(PORTB) 283 | case 2: DDRB |= mask; PORTB &= ~mask; break; 284 | #endif 285 | #if defined(PORTC) 286 | case 3: DDRC |= mask; PORTC &= ~mask; break; 287 | #endif 288 | #if defined(PORTD) 289 | case 4: DDRD |= mask; PORTD &= ~mask; break; 290 | #endif 291 | default:; 292 | } 293 | this->directTxPort = port; 294 | this->directTxMask = mask; 295 | this->TXInit(); 296 | } 297 | 298 | 299 | /*********************** RECEIVER INIT *************************/ 300 | 301 | void ManchesterRF::RXInit() { 302 | 303 | //setup timers depending on the microcontroller used 304 | 305 | #if defined( __AVR_ATtinyX5__ ) 306 | 307 | /* 308 | Timer 1 is used with a ATtiny85. 309 | http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf page 88 310 | How to find the correct value: (OCRxA +1) = F_CPU / prescaler / 1953.125 311 | OCR1C is 8 bit register 312 | */ 313 | 314 | if (0) { 315 | 316 | #if F_CPU == 1000000UL 317 | if (speedFactor == 1) { //preserve PWM 318 | 319 | } else { 320 | TCCR1 = _BV(CTC1) | _BV(CS12); // 1/8 prescaler 321 | OCR1C = (64 >> speedFactor) - 1; 322 | } 323 | #elif F_CPU == 8000000UL 324 | TCCR1 = _BV(CTC1) | _BV(CS12) | _BV(CS11) | _BV(CS10); // 1/64 prescaler 325 | OCR1C = (64 >> speedFactor) - 1; 326 | #elif F_CPU == 16000000UL 327 | TCCR1 = _BV(CTC1) | _BV(CS12) | _BV(CS11) | _BV(CS10); // 1/64 prescaler 328 | OCR1C = (128 >> speedFactor) - 1; 329 | #elif F_CPU == 16500000UL 330 | TCCR1 = _BV(CTC1) | _BV(CS12) | _BV(CS11) | _BV(CS10); // 1/64 prescaler 331 | OCR1C = (132 >> speedFactor) - 1; 332 | #else 333 | #error "Manchester library only supports 1mhz, 8mhz, 16mhz, 16.5Mhz clock speeds on ATtiny85 chip" 334 | #endif 335 | 336 | OCR1A = 0; // Trigger interrupt when TCNT1 is reset to 0 337 | TIMSK |= _BV(OCIE1A); // Turn on interrupt 338 | TCNT1 = 0; // Set counter to 0 339 | 340 | } else { //new 341 | 342 | unsigned long f = F_CPU >> (speedFactor); 343 | // unsigned int base_pulse_inc = 1 * 256 * 16 / (F_CPU / 1000000); 344 | 345 | if (f < 500000) { //processer not fast enough, increase pulse width instead 346 | TCCR1 &= B11110000; //clear old prescaller 347 | TCCR1 |= _BV(CS10); //set new prescaller to 1 348 | rx_pulse_width_inc = 16; 349 | if (f < 250000) rx_pulse_width_inc = 32; 350 | if (f < 125000) rx_pulse_width_inc = 64; 351 | 352 | } else { 353 | //timer 1 has only fast PWM 354 | byte prescaller = (f/500000); 355 | TCCR1 &= B11110000; //clear old prescaller 356 | TCCR1 |= B00001111 & (0 + MAN_log2(prescaller)); //set new prescaller 357 | rx_pulse_width_inc = 4; 358 | } 359 | //TIMSK is shared with timer 0 and timer 1 360 | TIMSK |= _BV(TOIE1); // Turn on interrupt on overflow 361 | 362 | } //new 363 | 364 | /* 365 | 366 | unsigned long f = F_CPU >> (speedFactor); 367 | unsigned int base_pulse_inc = 1 * 256 * 16 / (F_CPU / 1000000); 368 | 369 | if (f < 1000000) { 370 | TCCR2B = _BV(CS20); // 1/1 prescaler 371 | TCCR2A = _BV(WGM21) | _BV(WGM20); //fast PWM 372 | rx_pulse_width_inc = ((8 * 500000/f) * base_pulse_inc) >> 8; 373 | } else if (f < 4000000) { 374 | TCCR2B = _BV(CS20); // 1/1 prescaler 375 | TCCR2A = _BV(WGM20); //phase correct pwm 376 | rx_pulse_width_inc = ((8 * 1000000/f)* base_pulse_inc) >> 8; 377 | } else if (f < 8000000) { 378 | TCCR2B = _BV(CS21); // 1/8 prescaler 379 | TCCR2A = _BV(WGM21) | _BV(WGM20); //fast PWM 380 | rx_pulse_width_inc = (8 * base_pulse_inc) >> 8; 381 | } else { 382 | TCCR2B = _BV(CS21); // 1/8 prescaler 383 | TCCR2A = _BV(WGM20); //phase correct pwm 384 | rx_pulse_width_inc = ((8 * 8000000/f)* base_pulse_inc) >> 8; 385 | } 386 | 387 | TIMSK2 = _BV(TOIE2); // Turn on interrupt 388 | 389 | */ 390 | 391 | 392 | #elif defined( __AVR_ATtinyX4__ ) 393 | 394 | /* 395 | Timer 1 is used with a ATtiny84. 396 | http://www.atmel.com/Images/doc8006.pdf page 111 397 | How to find the correct value: (OCRxA +1) = F_CPU / prescaler / 1953.125 398 | OCR1A is 8 bit register 399 | */ 400 | 401 | if (0) { //old 402 | #if F_CPU == 1000000UL 403 | TCCR1B = _BV(WGM12) | _BV(CS11); // 1/8 prescaler 404 | OCR1A = (64 >> speedFactor) - 1; 405 | #elif F_CPU == 8000000UL 406 | TCCR1B = _BV(WGM12) | _BV(CS11) | _BV(CS10); // 1/64 prescaler 407 | OCR1A = (64 >> speedFactor) - 1; 408 | #elif F_CPU == 16000000UL 409 | TCCR1B = _BV(WGM12) | _BV(CS11) | _BV(CS10); // 1/64 prescaler 410 | OCR1A = (128 >> speedFactor) - 1; 411 | #else 412 | #error "Manchester library only supports 1mhz, 8mhz, 16mhz on ATtiny84" 413 | #endif 414 | 415 | TIMSK1 |= _BV(OCIE1A); // Turn on interrupt 416 | TCNT1 = 0; // Set counter to 0 417 | 418 | } else { //new PWM preserving 419 | 420 | //TIMER 1 and TIMER 0 share the same prescaller, changing the prescaller will effect millis() 421 | unsigned long f = F_CPU >> (speedFactor); 422 | unsigned int base_pulse_inc = 1 * 256 * 16 / (F_CPU / 1000000); 423 | /* 424 | F_CPU 1Mhz 425 | speedFactor | f 426 | 0 - 1 427 | 1 - 0.5 428 | 2 - 0.25 429 | 3 - 0.125 430 | 431 | F_CPU 8Mhz 432 | speedFactor | f 433 | 0 - 8 434 | 1 - 4 435 | 2 - 2 436 | 3 - 1 437 | 4 - 0.5 438 | 5 - 0.25 439 | 440 | F_CPU 16Mhz 441 | speedFactor | f 442 | 0 - 16 443 | 1 - 8 444 | 2 - 4 445 | 3 - 2 446 | 4 - 1 447 | 5 - 0.5 448 | */ 449 | 450 | 451 | if (f < 2000000) { 452 | TCCR1B &= B11111000; //clear the old prescaller 453 | TCCR1B |= _BV(CS10); //set new prescaller to 1 454 | //set fast PWM 8bit 455 | TCCR1B &= B11100111; //clear old value 456 | TCCR1A &= B11111100; //clear old value 457 | TCCR1B |= _BV(WGM12); //set new value 458 | TCCR1A |= _BV(WGM10); //set new value 459 | rx_pulse_width_inc = 8 * 500000/f; 460 | } else if (f < 4000000) { 461 | TCCR1B &= B11111000; //clear the old prescaller 462 | TCCR1B |= _BV(CS10); //set new prescaller to 1 463 | //phase correct PWM 8bit 464 | TCCR1B &= B11100111; //clear old value 465 | TCCR1A &= B11111100; //clear old value 466 | TCCR1A |= _BV(WGM10); //set new value 467 | rx_pulse_width_inc = 8 * 1000000/f; 468 | } else if (f < 8000000) { 469 | TCCR1B &= B11111000; //clear the old prescaller 470 | TCCR1B |= _BV(CS11); //set new prescaller to 8 471 | //set fast PWM 8bit 472 | TCCR1B &= B11100111; //clear old value 473 | TCCR1A &= B11111100; //clear old value 474 | TCCR1B |= _BV(WGM12); //set new value 475 | TCCR1A |= _BV(WGM10); //set new value 476 | rx_pulse_width_inc = 8; 477 | } else { 478 | TCCR1B &= B11111000; //clear the old prescaller 479 | TCCR1B |= _BV(CS11); //set new prescaller to 8 480 | //phase correct PWM 8bit 481 | TCCR1B &= B11100111; //clear old value 482 | TCCR1A &= B11111100; //clear old value 483 | TCCR1A |= _BV(WGM10); //set new value 484 | rx_pulse_width_inc = 8 * 8000000/f; 485 | } 486 | 487 | TIMSK1 = _BV(TOIE1); // Turn on interrupt 488 | } 489 | #elif defined(__AVR_ATmega32U4__) 490 | 491 | /* 492 | Timer 3 is used with a ATMega32U4. 493 | http://www.atmel.com/Images/doc7766.pdf page 133 494 | How to find the correct value: (OCRxA +1) = F_CPU / prescaler / 1953.125 495 | OCR3A is 16 bit register 496 | */ 497 | 498 | TCCR3B = _BV(WGM32) | _BV(CS31); // 1/8 prescaler 499 | #if F_CPU == 1000000UL 500 | OCR3A = (64 >> speedFactor) - 1; 501 | #elif F_CPU == 8000000UL 502 | OCR3A = (512 >> speedFactor) - 1; 503 | #elif F_CPU == 16000000UL 504 | OCR3A = (1024 >> speedFactor) - 1; 505 | #else 506 | #error "Manchester library only supports 1mhz, 8mhz, 16mhz on ATMega32U4" 507 | #endif 508 | 509 | TCCR3A = 0; // reset counter on match 510 | TIFR3 = _BV(OCF3A); // clear interrupt flag 511 | TIMSK3 = _BV(OCIE3A); // Turn on interrupt 512 | TCNT3 = 0; // Set counter to 0 513 | 514 | #elif defined(__AVR_ATmega8__) 515 | 516 | /* 517 | Timer/counter 1 is used with ATmega8. 518 | http://www.atmel.com/Images/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf page 99 519 | How to find the correct value: (OCRxA +1) = F_CPU / prescaler / 1953.125 520 | OCR1A is 16 bit register 521 | */ 522 | 523 | TCCR1A = _BV(WGM12); // reset counter on match 524 | TCCR1B = _BV(CS11); // 1/8 prescaler 525 | #if F_CPU == 1000000UL 526 | OCR1A = (64 >> speedFactor) - 1; 527 | #elif F_CPU == 8000000UL 528 | OCR1A = (512 >> speedFactor) - 1; 529 | #elif F_CPU == 16000000UL 530 | OCR1A = (1024 >> speedFactor) - 1; 531 | #else 532 | #error "Manchester library only supports 1Mhz, 8mhz, 16mhz on ATMega8" 533 | #endif 534 | TIFR = _BV(OCF1A); // clear interrupt flag 535 | TIMSK = _BV(OCIE1A); // Turn on interrupt 536 | TCNT1 = 0; // Set counter to 0 537 | 538 | #elif defined(__AVR_ATmega328P__) 539 | 540 | /* 541 | Timer 2 is used with a ATMega328. 542 | pins 11 and 3 are connected to Timer2 543 | http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf page 162 544 | */ 545 | 546 | /* 547 | F_CPU 1Mhz 548 | speedFactor | f 549 | 0 - 1 550 | 1 - 0.5 551 | 2 - 0.25 552 | 3 - 0.125 553 | 554 | F_CPU 8Mhz 555 | speedFactor | f 556 | 0 - 8 557 | 1 - 4 558 | 2 - 2 559 | 3 - 1 560 | 4 - 0.5 561 | 5 - 0.25 562 | 563 | F_CPU 16Mhz 564 | speedFactor | f 565 | 0 - 16 566 | 1 - 8 567 | 2 - 4 568 | 3 - 2 569 | 4 - 1 570 | 5 - 0.5 571 | */ 572 | 573 | unsigned long f = F_CPU >> (speedFactor); 574 | unsigned int base_pulse_inc = 1 * 256 * 16 / (F_CPU / 1000000); 575 | 576 | if (f < 2000000) { 577 | TCCR2B = _BV(CS20); // 1/1 prescaler 578 | TCCR2A = _BV(WGM21) | _BV(WGM20); //fast PWM 579 | rx_pulse_width_inc = ((8 * 500000/f) * base_pulse_inc) >> 8; 580 | } else if (f < 4000000) { 581 | TCCR2B = _BV(CS20); // 1/1 prescaler 582 | TCCR2A = _BV(WGM20); //phase correct pwm 583 | rx_pulse_width_inc = ((8 * 1000000/f)* base_pulse_inc) >> 8; 584 | // } else if (f < 8000000) { 585 | // TCCR2B = _BV(CS21); // 1/8 prescaler 586 | // TCCR2A = _BV(WGM21) | _BV(WGM20); //fast PWM 587 | // rx_pulse_width_inc = (8 * base_pulse_inc) >> 8; 588 | } else { 589 | TCCR2B = _BV(CS21); // 1/8 prescaler 590 | TCCR2A = _BV(WGM20); //phase correct pwm 591 | rx_pulse_width_inc = ((8 * 8000000/f)* base_pulse_inc) >> 8; 592 | } 593 | 594 | TIMSK2 = _BV(TOIE2); // Turn on interrupt 595 | 596 | 597 | #elif defined(__AVR_ATmega1284P__) 598 | 599 | /* 600 | Timer 3 is used on ATMega1284, Timer3 controlls PWM on SPI pins 601 | http://www.atmel.com/images/doc8059.pdf page 134 602 | How to find the correct value: (OCRxA +1) = F_CPU / prescaler / 1953.125 603 | OCR3A is 16 bit register 604 | */ 605 | 606 | if (0) { //old method 607 | 608 | TCCR3A = _BV(WGM32); // reset counter on match 609 | #if F_CPU == 1000000UL 610 | TCCR3B = _BV(CS30); // 1/1 prescaler 611 | OCR3A = (512 >> speedFactor) - 1; 612 | #elif F_CPU == 8000000UL 613 | TCCR3B = _BV(CS31); // 1/8 prescaler 614 | OCR3A = (512 >> speedFactor) - 1; 615 | #elif F_CPU == 12000000UL 616 | TCCR3B = _BV(CS31); // 1/8 prescaler 617 | OCR3A = (768 >> speedFactor) - 1; 618 | #elif F_CPU == 16000000UL 619 | TCCR3B = _BV(CS31); // 1/8 prescaler 620 | OCR3A = (1024 >> speedFactor) - 1; 621 | #elif F_CPU == 20000000UL 622 | TCCR3B = _BV(CS31); // 1/8 prescaler 623 | OCR3A = (1280 >> speedFactor) - 1; 624 | #elif F_CPU == 24000000UL 625 | TCCR3B = _BV(CS31); // 1/8 prescaler 626 | OCR3A = (1536 >> speedFactor) - 1; 627 | #else 628 | #error "Manchester library only supports 1Mhz, 8Mhz, 12Mhz, 16Mhz, 20Mhz, 24Mhz on ATMega1284" 629 | #endif 630 | TIMSK3 = _BV(OCIE3A); // Turn on interrupt 631 | TCNT3 = 0; // Set counter to 0 632 | 633 | } else { //new PWM preserving method 634 | 635 | unsigned long f = F_CPU >> (speedFactor); 636 | unsigned int base_pulse_inc = 1 * 256 * 16 / (F_CPU / 1000000); 637 | 638 | if (f < 1000000) { 639 | TCCR3B &= B11111000; //clear the prescaler 640 | TCCR3B |= _BV(CS30); //prescaler 1 641 | //fast 8 bit PWM 642 | TCCR3A &= B11111100; //clear old value 643 | TCCR3B &= B11100111; //clear old value 644 | TCCR3A |= _BV(WGM30); 645 | TCCR3B |= _BV(WGM32); 646 | rx_pulse_width_inc = 8; //((8 * 500000/f) * base_pulse_inc) >> 8; 647 | if (f < 500000) { rx_pulse_width_inc = 13; } 648 | } else if (f < 4000000) { //assume 16Mhz, (sF = 4, f=1M) (sF = 3, f=2M) 649 | TCCR3B &= B11111000; //clear the prescaler 650 | TCCR3B |= _BV(CS30); //prescaler 1 651 | //phase correct 8 bit PWM 652 | TCCR3A &= B11111100; //clear old value 653 | TCCR3B &= B11100111; //clear old value 654 | TCCR3A |= _BV(WGM30); 655 | //(128 << speedFactor) / (Mhz�) 656 | rx_pulse_width_inc = 8; //((8 * 1000000/f)* base_pulse_inc) >> 8; //only 6 and 7 works on 20MHz 657 | } else if (f < 8000000) { 658 | TCCR3B &= B11111000; //clear the prescaler 659 | TCCR3B |= _BV(CS31); //prescaler 8 660 | //fast 8 bit PWM 661 | TCCR3A &= B11111100; //clear old value 662 | TCCR3B &= B11100111; //clear old value 663 | TCCR3A |= _BV(WGM30); 664 | TCCR3B |= _BV(WGM32); 665 | rx_pulse_width_inc = (8 * base_pulse_inc) >> 8; 666 | } else { 667 | TCCR3B &= B11111000; //clear the prescaler 668 | TCCR3B |= _BV(CS31); //prescaler 8 669 | //phase correct 8 bit PWM 670 | TCCR3A &= B11111100; //clear old value 671 | TCCR3B &= B11100111; //clear old value 672 | TCCR3A |= _BV(WGM30); 673 | rx_pulse_width_inc = ((8 * 8000000/f)* base_pulse_inc) >> 8; 674 | } 675 | 676 | TIMSK3 = _BV(TOIE3); // Turn on interrupt 677 | 678 | 679 | 680 | } 681 | 682 | #else 683 | #error "Manchester library doesnt support your microcontroller" 684 | #endif 685 | 686 | ::rx_mode = RX_MODE_PRE; 687 | } 688 | 689 | 690 | void ManchesterRF::RXInit(uint8_t pin) { 691 | ::RxPin = pin; 692 | pinMode(pin, INPUT); 693 | this->pin2PortMask(pin, ::directRxPort, ::directRxMask); 694 | this->RXInit(); 695 | } 696 | 697 | 698 | void ManchesterRF::RXInit(uint8_t port, uint8_t mask) { 699 | ::directRxPort = port; 700 | ::directRxMask = mask; 701 | this->RXInit(); 702 | } 703 | 704 | void ManchesterRF::setDebugPortMask(uint8_t port, uint8_t mask) { 705 | ::directDebugPort = port; 706 | ::directDebugMask = mask; 707 | } 708 | 709 | 710 | /* 711 | void ManchesterRF::setup(uint8_t Tpin, uint8_t Rpin, uint8_t SF) 712 | { 713 | setupTransmit(Tpin, SF); 714 | setupReceive(Rpin, SF); 715 | } 716 | */ 717 | 718 | /* 719 | void ManchesterRF::transmit(uint16_t data) 720 | { 721 | uint8_t byteData[2] = {data >> 8, data & 0xFF}; 722 | transmitArray(2, byteData); 723 | } 724 | */ 725 | 726 | 727 | size_t ManchesterRF::write(uint8_t value) { 728 | //TODO 729 | 730 | return 1; 731 | } 732 | 733 | 734 | 735 | void ManchesterRF::sendZero(void) { 736 | if (this->directTxPort && this->directTxMask) { //use direct port manipulation (much faster) 737 | delayMicroseconds(delay11); 738 | //go HIGH 739 | switch(this->directTxPort) { 740 | #if defined(PORTA) 741 | case 1: PORTA |= this->directTxMask; break; 742 | #endif 743 | #if defined(PORTB) 744 | case 2: PORTB |= this->directTxMask; break; 745 | #endif 746 | #if defined(PORTC) 747 | case 3: PORTC |= this->directTxMask; break; 748 | #endif 749 | #if defined(PORTD) 750 | case 4: PORTD |= this->directTxMask; break; 751 | #endif 752 | default:; 753 | } 754 | delayMicroseconds(delay20); 755 | 756 | //go LOW 757 | switch(this->directTxPort) { 758 | #if defined(PORTA) 759 | case 1: PORTA &= ~this->directTxMask; break; 760 | #endif 761 | #if defined(PORTB) 762 | case 2: PORTB &= ~this->directTxMask; break; 763 | #endif 764 | #if defined(PORTC) 765 | case 3: PORTC &= ~this->directTxMask; break; 766 | #endif 767 | #if defined(PORTD) 768 | case 4: PORTD &= ~this->directTxMask; break; 769 | #endif 770 | default:; 771 | } 772 | } else { 773 | delayMicroseconds(delay11); 774 | digitalWrite(TxPin, HIGH); 775 | 776 | delayMicroseconds(delay20); 777 | digitalWrite(TxPin, LOW); 778 | } 779 | }//end of send a zero 780 | 781 | 782 | void ManchesterRF::sendOne(void) { 783 | if (directTxMask) { //use direct port manipulation (much faster) 784 | delayMicroseconds(delay10); 785 | //go LOW 786 | switch(this->directTxPort) { 787 | #if defined(PORTA) 788 | case 1: PORTA &= ~this->directTxMask; break; 789 | #endif 790 | #if defined(PORTB) 791 | case 2: PORTB &= ~this->directTxMask; break; 792 | #endif 793 | #if defined(PORTC) 794 | case 3: PORTC &= ~this->directTxMask; break; 795 | #endif 796 | #if defined(PORTD) 797 | case 4: PORTD &= ~this->directTxMask; break; 798 | #endif 799 | default:; 800 | } 801 | 802 | delayMicroseconds(delay21); 803 | //go HIGH 804 | switch(this->directTxPort) { 805 | #if defined(PORTA) 806 | case 1: PORTA |= this->directTxMask; break; 807 | #endif 808 | #if defined(PORTB) 809 | case 2: PORTB |= this->directTxMask; break; 810 | #endif 811 | #if defined(PORTC) 812 | case 3: PORTC |= this->directTxMask; break; 813 | #endif 814 | #if defined(PORTD) 815 | case 4: PORTD |= this->directTxMask; break; 816 | #endif 817 | default:; 818 | } 819 | } else { 820 | delayMicroseconds(delay10); 821 | digitalWrite(TxPin, LOW); 822 | 823 | delayMicroseconds(delay21); 824 | digitalWrite(TxPin, HIGH); 825 | } 826 | }//end of send one 827 | 828 | 829 | /* 830 | The 433.92 Mhz receivers have AGC, if no signal is present the gain will be set 831 | to its highest level. 832 | 833 | In this condition it will switch high to low at random intervals due to input noise. 834 | A CRO connected to the data line looks like 433.92 is full of transmissions. 835 | 836 | Any ASK transmission method must first sent a capture signal of 101010........ 837 | When the receiver has adjusted its AGC to the required level for the transmisssion 838 | the actual data transmission can occur. 839 | 840 | We send 14 0's 1010... It takes 1 to 3 10's for the receiver to adjust to 841 | the transmit level. 842 | 843 | The receiver waits until we have at least 10 10's and then a start pulse 01. 844 | The receiver is then operating correctly and we have locked onto the transmission. 845 | */ 846 | uint8_t ManchesterRF::transmitArray(uint8_t size, uint8_t *data) { 847 | if (size == 0) return 0; 848 | 849 | #if F_CPU < 88000000UL 850 | char cSREG; 851 | cSREG = SREG; /* store SREG value */ 852 | cli(); 853 | #endif 854 | 855 | //send preamble 856 | for( uint8_t i = 0; i < 14; i++) { 857 | sendZero(); 858 | //match the overhead in the data cycle, I have to do it this way, so optimizer won't mess with it 859 | #if F_CPU < 88000000UL 860 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 861 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 862 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 863 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 864 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 865 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 866 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 867 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 868 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 869 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 870 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 871 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 872 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 873 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 874 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 875 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 876 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 877 | #endif 878 | } 879 | 880 | // Send a single 1 881 | sendOne(); //start data pulse 882 | 883 | 884 | //match the overhead in the data cycle, I have to do it this way, so optimizer won't mess with it 885 | #if F_CPU < 88000000UL 886 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 887 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 888 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 889 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 890 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 891 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 892 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 893 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 894 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 895 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 896 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 897 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 898 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 899 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 900 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 901 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 902 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 903 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 904 | __asm__ __volatile__ ("mov r0, r0"); //wait one cycle 905 | #endif 906 | 907 | // Send the user data 908 | 909 | for (uint8_t i = 0; i < size; i++) { 910 | uint8_t mask = 0x01; //mask to send bits 911 | //uint8_t d = data[i] ^ DECOUPLING_MASK; 912 | for (uint8_t j = 0; j < 8; j++) { 913 | if (((data[i] ^ DECOUPLING_MASK) & mask) == 0) 914 | sendZero(); 915 | else 916 | sendOne(); 917 | mask <<= 1; //get next bit 918 | }//end of byte 919 | }//end of data 920 | 921 | // Send terminating 0 to correctly terminate the previous bit and to turn the transmitter off 922 | sendZero(); 923 | sendZero(); 924 | 925 | #if F_CPU < 88000000UL 926 | SREG = cSREG; 927 | #endif 928 | return size; 929 | }//end of send the data 930 | 931 | 932 | uint8_t ManchesterRF::receiveArray(uint8_t &size, uint8_t **data) { 933 | if (MAN_IS_BUFF_EMPTY) return 0; 934 | size = man_rx_buff[man_rx_buff_start][0]; 935 | *data = &man_rx_buff[man_rx_buff_start][1]; 936 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 937 | return 1; 938 | } 939 | 940 | 941 | //TODO use repairing codes perhabs? 942 | //http://en.wikipedia.org/wiki/Hamming_code 943 | 944 | /* 945 | format of the message including checksum and ID 946 | 947 | [0][1][2][3][4][5][6][7][8][9][a][b][c][d][e][f] 948 | [ ID ][ checksum ][ data ] 949 | checksum = ID xor data[7:4] xor data[3:0] xor 0b0011 950 | 951 | */ 952 | 953 | /* 954 | //decode 8 bit payload and 4 bit ID from the message, return true if checksum is correct, otherwise false 955 | uint8_t ManchesterRF::decodeMessage(uint16_t m, uint8_t &id, uint8_t &data) 956 | { 957 | //extract components 958 | data = (m & 0xFF); 959 | id = (m >> 12); 960 | uint8_t ch = (m >> 8) & 0b1111; //checksum received 961 | //calculate checksum 962 | uint8_t ech = (id ^ data ^ (data >> 4) ^ 0b0011) & 0b1111; //checksum expected 963 | return ch == ech; 964 | } 965 | 966 | //encode 8 bit payload, 4 bit ID and 4 bit checksum into 16 bit 967 | uint16_t ManchesterRF::encodeMessage(uint8_t id, uint8_t data) { 968 | uint8_t chsum = (id ^ data ^ (data >> 4) ^ 0b0011) & 0b1111; 969 | uint16_t m = ((id) << 12) | (chsum << 8) | (data); 970 | return m; 971 | } 972 | */ 973 | 974 | 975 | 976 | /* 977 | #define MAN_IS_BUFF_EMPTY (man_rx_buff_end == man_rx_buff_start) 978 | #define MAN_IS_BUFF_FULL ((man_rx_buff_end+1) % MAN_BUF_SIZE == man_rx_buff_start) 979 | 980 | static uint8_t man_rx_buff[MAN_BUF_SIZE][MAN_MESSAGE_SIZE]; 981 | static uint8_t man_rx_buff_start = 0; 982 | static uint8_t man_rx_buff_end = 0; 983 | */ 984 | 985 | /* 986 | packet format 987 | [from][ to ][meta][payload][payload][payload] ... [checksum] 988 | 989 | */ 990 | 991 | 992 | uint8_t ManchesterRF::transmitPacket(uint8_t size, uint8_t from, uint8_t to, uint8_t meta, uint8_t *payload) { 993 | ::man_tx_buff[0] = from; 994 | ::man_tx_buff[1] = to; 995 | ::man_tx_buff[2] = meta; 996 | // ::man_tx_buff[3] = 111; 997 | // ::man_tx_buff[4] = 222; 998 | for (uint8_t i = 0; i < size && i < 10; i++) { 999 | ::man_tx_buff[i + 3] = payload[i]; 1000 | } 1001 | 1002 | //calculate the modification of a Fletcher checksum 1003 | uint8_t c0 = size + 4; 1004 | uint8_t c1 = size + 4; 1005 | for(int i = 0; i < size + 3; i++) { //zeroth element is the size, it's not part of the packet, but we will add it as an extra check; sizeth element is the checksum we are calculating 1006 | c0 += ::man_tx_buff[i]; 1007 | c1 += c0; 1008 | } 1009 | c1 ^= c0; 1010 | ::man_tx_buff[size + 3] = c1; 1011 | 1012 | return this->transmitArray(size + 4, ::man_tx_buff); 1013 | } 1014 | 1015 | uint8_t ManchesterRF::receivePacket(uint8_t &size, uint8_t &from, uint8_t &to, uint8_t &meta, uint8_t **payload) { 1016 | if (MAN_IS_BUFF_EMPTY) return 0; 1017 | if (man_rx_buff[man_rx_buff_start][0] < 4) { //not enough bytes for a valid packet 1018 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1019 | return 0; 1020 | } 1021 | uint8_t msize = man_rx_buff[man_rx_buff_start][0]; 1022 | size = msize - 4; //payload size 1023 | from = man_rx_buff[man_rx_buff_start][1]; 1024 | to = man_rx_buff[man_rx_buff_start][2]; 1025 | meta = man_rx_buff[man_rx_buff_start][3]; 1026 | *payload = &man_rx_buff[man_rx_buff_start][4]; 1027 | uint8_t ch = man_rx_buff[man_rx_buff_start][msize]; 1028 | 1029 | //calculate the modification of a Fletcher checksum 1030 | uint8_t c0 = 0; 1031 | uint8_t c1 = 0; 1032 | for(int i = 0; i < msize; i++) { //zeroth element is the size, it's not part of the packet, but we will add it as an extra check; sizeth element is the checksum we are calculating 1033 | c0 += man_rx_buff[man_rx_buff_start][i]; 1034 | c1 += c0; 1035 | } 1036 | c1 ^= c0; 1037 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1038 | if (ch == c1) return 1; 1039 | return 0; 1040 | } 1041 | 1042 | 1043 | uint8_t ManchesterRF::transmitByte(uint8_t data) { 1044 | return this->transmitArray(1, &data); 1045 | } 1046 | 1047 | uint8_t ManchesterRF::receiveByte(uint8_t &data) { 1048 | if (MAN_IS_BUFF_EMPTY) return 0; 1049 | if (man_rx_buff[man_rx_buff_start][0] < 1) { //not enough bytes 1050 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1051 | return 0; 1052 | } 1053 | data = man_rx_buff[man_rx_buff_start][1]; 1054 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1055 | return 1; 1056 | } 1057 | 1058 | 1059 | uint8_t ManchesterRF::transmitByte(uint8_t data0, uint8_t data1) { 1060 | ::man_tx_buff[0] = data0; 1061 | ::man_tx_buff[1] = data1; 1062 | return this->transmitArray(2, ::man_tx_buff); 1063 | } 1064 | 1065 | uint8_t ManchesterRF::receiveByte(uint8_t &data0, uint8_t &data1) { 1066 | if (MAN_IS_BUFF_EMPTY) return 0; 1067 | if (man_rx_buff[man_rx_buff_start][0] < 2) { //not enough bytes 1068 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1069 | return 0; 1070 | } 1071 | data0 = man_rx_buff[man_rx_buff_start][1]; 1072 | data1 = man_rx_buff[man_rx_buff_start][2]; 1073 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1074 | return 1; 1075 | } 1076 | 1077 | uint8_t ManchesterRF::transmitByte(uint8_t data0, uint8_t data1, uint8_t data2) { 1078 | ::man_tx_buff[0] = data0; 1079 | ::man_tx_buff[1] = data1; 1080 | ::man_tx_buff[2] = data2; 1081 | return this->transmitArray(3, ::man_tx_buff); 1082 | } 1083 | 1084 | uint8_t ManchesterRF::receiveByte(uint8_t &data0, uint8_t &data1, uint8_t &data2) { 1085 | if (MAN_IS_BUFF_EMPTY) return 0; 1086 | if (man_rx_buff[man_rx_buff_start][0] < 3) { //not enough bytes 1087 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1088 | return 0; 1089 | } 1090 | data0 = man_rx_buff[man_rx_buff_start][1]; 1091 | data1 = man_rx_buff[man_rx_buff_start][2]; 1092 | data2 = man_rx_buff[man_rx_buff_start][3]; 1093 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1094 | return 1; 1095 | } 1096 | 1097 | 1098 | uint8_t ManchesterRF::transmitWord(uint16_t data) { 1099 | return this->transmitArray(2, (uint8_t*)&data); 1100 | } 1101 | 1102 | 1103 | uint8_t ManchesterRF::receiveWord(uint16_t &data) { 1104 | if (MAN_IS_BUFF_EMPTY) return 0; 1105 | if (man_rx_buff[man_rx_buff_start][0] < 2) { //not enough bytes for a valid word 1106 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1107 | return 0; 1108 | } 1109 | data = (man_rx_buff[man_rx_buff_start][1] << 8 ) + man_rx_buff[man_rx_buff_start][2]; 1110 | man_rx_buff_start = (man_rx_buff_start + 1) % MAN_BUF_SIZE; //remove message from the buffer 1111 | return 1; 1112 | } 1113 | 1114 | int ManchesterRF::available() { 1115 | return !MAN_IS_BUFF_EMPTY; 1116 | } 1117 | 1118 | 1119 | int ManchesterRF::peek() { //TODO 1120 | return 0; 1121 | } 1122 | 1123 | 1124 | int ManchesterRF::read() { //TODO 1125 | return 0; 1126 | } 1127 | 1128 | 1129 | void ManchesterRF::flush() { //TODO 1130 | 1131 | } 1132 | 1133 | 1134 | /* 1135 | void ManchesterRF::beginReceiveArray(uint8_t maxBytes, uint8_t *data) { 1136 | ::MANRX_BeginReceiveBytes(maxBytes, data); 1137 | } 1138 | 1139 | */ 1140 | 1141 | void ManchesterRF::beginReceive(void) { 1142 | ::MANRX_BeginReceive(); 1143 | } 1144 | 1145 | /* 1146 | uint8_t ManchesterRF::receiveComplete(void) { 1147 | return ::MANRX_ReceiveComplete(); 1148 | } 1149 | */ 1150 | 1151 | /* 1152 | uint16_t ManchesterRF::getMessage(void) { 1153 | return ::MANRX_GetMessage(); 1154 | } 1155 | */ 1156 | 1157 | void ManchesterRF::stopReceive(void) { 1158 | ::MANRX_StopReceive(); 1159 | } 1160 | 1161 | 1162 | 1163 | 1164 | void MANRX_BeginReceive(void) { 1165 | // rx_maxBytes = 2; 1166 | // rx_data = rx_default_data; 1167 | rx_mode = RX_MODE_PRE; 1168 | } 1169 | 1170 | void MANRX_BeginReceiveBytes(uint8_t maxBytes, uint8_t *data) { 1171 | // rx_maxBytes = maxBytes; 1172 | // rx_data = data; 1173 | rx_mode = RX_MODE_PRE; 1174 | } 1175 | 1176 | void MANRX_StopReceive(void) { 1177 | rx_mode = RX_MODE_IDLE; 1178 | } 1179 | 1180 | 1181 | 1182 | //rx_manBits, &rx_numMB, &rx_curByte 1183 | void AddManBit(uint8_t bit) { 1184 | rx_manBits <<= 1; 1185 | if (bit) rx_manBits |= 0x01; 1186 | (rx_numMB)++; 1187 | if (rx_numMB == 16) { 1188 | uint8_t newData = 0; 1189 | for (int8_t i = 0; i < 8; i++) { 1190 | // rx_manBits holds 16 bits of manchester data 1191 | // 1 = LO,HI 1192 | // 0 = HI,LO 1193 | // We can decode each bit by looking at the bottom bit of each pair. 1194 | newData <<= 1; 1195 | newData |= (rx_manBits & 1); // store the one 1196 | rx_manBits = rx_manBits >> 2; //get next data bit 1197 | } 1198 | 1199 | man_rx_buff[man_rx_buff_end][(rx_curByte) +1] = newData ^ DECOUPLING_MASK; 1200 | man_rx_buff[man_rx_buff_end][0] = (rx_curByte)+1; 1201 | 1202 | //data[rx_curByte] = newData ^ DECOUPLING_MASK; 1203 | (rx_curByte)++; 1204 | rx_numMB = 0; 1205 | } 1206 | } 1207 | 1208 | 1209 | void MAN_RX_INTERRUPT_HANDLER() { 1210 | if (rx_mode < RX_MODE_MSG) {//receiving something 1211 | 1212 | 1213 | // Increment counter 1214 | rx_pulse_width += rx_pulse_width_inc; 1215 | 1216 | 1217 | // Check receive pin 1218 | if (::directRxPort && ::directRxMask) { //use direct port manipulation (much faster) 1219 | 1220 | switch(::directRxPort) { 1221 | #if defined(PINA) 1222 | case 1: rx_sample = PINA & ::directRxMask; break; 1223 | #endif 1224 | #if defined(PINB) 1225 | case 2: rx_sample = PINB & ::directRxMask; break; 1226 | #endif 1227 | #if defined(PINC) 1228 | case 3: rx_sample = PINC & ::directRxMask; break; 1229 | #endif 1230 | #if defined(PIND) 1231 | case 4: rx_sample = PIND & ::directRxMask; break; 1232 | #endif 1233 | default: rx_sample = 0; 1234 | } 1235 | 1236 | } else { 1237 | rx_sample = digitalRead(RxPin); 1238 | } 1239 | 1240 | 1241 | if (rx_sample != rx_last_sample) { //pin has changed 1242 | // PIND |= (1<<7); 1243 | // PINA |= (1<<0); 1244 | //sss = rx_pulse_width; 1245 | isranie++; 1246 | sranie[isranie] = rx_pulse_width; 1247 | if (rx_mode == RX_MODE_PRE) { 1248 | if (rx_sample) { // Wait for first transition to HIGH 1249 | rx_pulse_width = 0; 1250 | rx_sync_count = 0; 1251 | rx_mode = RX_MODE_SYNC; 1252 | isranie = 0; 1253 | } 1254 | } else if (rx_mode == RX_MODE_SYNC) { // Initial sync block 1255 | 1256 | if (((rx_sync_count < 20) || (rx_last_sample)) && ((rx_pulse_width < MinCount) || (rx_pulse_width > MaxCount))) { 1257 | // First 20 bits and all 1 bits are expected to be regular 1258 | // Transition was too slow/fast 1259 | rx_mode = RX_MODE_PRE; 1260 | isranie = 0; 1261 | } else if ((!rx_last_sample) && ((rx_pulse_width < MinCount) || (rx_pulse_width > MaxLongCount))) { 1262 | // 0 bits after the 20th bit are allowed to be a double bit 1263 | // Transition was too slow/fast 1264 | rx_mode = RX_MODE_PRE; 1265 | isranie = 0; 1266 | } else { 1267 | rx_sync_count++; 1268 | if ((!rx_last_sample) && (rx_sync_count >= 20) && (rx_pulse_width >= MinLongCount)) { 1269 | // We have seen at least 10 regular transitions 1270 | // Lock sequence ends with unencoded bits 01 1271 | // This is encoded and TX as HI,LO,LO,HI 1272 | // We have seen a long low - we are now locked! 1273 | // PINA |= (1<<3); //toggle debug pin A3 on tiny84 1274 | rx_mode = RX_MODE_DATA; 1275 | rx_manBits = 0; 1276 | rx_numMB = 0; 1277 | rx_curByte = 0; 1278 | } else if (rx_sync_count >= 64) { //preamble too long 1279 | rx_mode = RX_MODE_PRE; //TODO do we really need to drop the packet? 1280 | isranie = 0; 1281 | } 1282 | rx_pulse_width = 0; 1283 | } 1284 | } else if (rx_mode == RX_MODE_DATA) { // Receive data 1285 | 1286 | if ((rx_pulse_width < MinCount) || (rx_pulse_width > MaxLongCount)) {// wrong pulse length 1287 | rx_mode = RX_MODE_PRE; 1288 | if (rx_curByte > 0) { //if received something, save what we have 1289 | if (!MAN_IS_BUFF_FULL) man_rx_buff_end = (man_rx_buff_end+1) % MAN_BUF_SIZE; 1290 | } 1291 | isranie = 0; 1292 | } else { 1293 | if (rx_pulse_width >= MinLongCount) {// was the previous bit a double bit? 1294 | AddManBit(rx_last_sample); 1295 | } 1296 | if ((rx_sample) && (rx_curByte >= MAN_MESSAGE_SIZE)) { //message too long, truncate it and start over 1297 | // rx_mode = RX_MODE_MSG; 1298 | isranie = 0; 1299 | rx_mode = RX_MODE_PRE; 1300 | if (!MAN_IS_BUFF_FULL) man_rx_buff_end = (man_rx_buff_end+1) % MAN_BUF_SIZE; 1301 | } else { 1302 | // Add the current bit 1303 | AddManBit(rx_sample); 1304 | rx_pulse_width = 0; 1305 | } 1306 | } 1307 | } 1308 | // Get ready for next loop 1309 | rx_last_sample = rx_sample; 1310 | } 1311 | } 1312 | } //MAN_RX_INTERRUPT_HANDLER 1313 | 1314 | 1315 | /*********** TIMER COMPARATOR INTERRUPT **********/ 1316 | 1317 | #if defined( __AVR_ATtinyX5__ ) 1318 | ISR(TIMER1_COMPA_vect) 1319 | #elif defined( __AVR_ATtinyX4__ ) 1320 | ISR(TIM1_COMPA_vect) 1321 | #elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1284P__) 1322 | ISR(TIMER3_COMPA_vect) 1323 | #elif defined(__AVR_ATmega328P__) 1324 | ISR(TIMER2_COMPA_vect) 1325 | #else 1326 | #error "Manchester library doesnt support your microcontroller" 1327 | #endif 1328 | { 1329 | // PIND |= (1<<7); //toggle debug pin 7 1330 | MAN_RX_INTERRUPT_HANDLER(); 1331 | } 1332 | 1333 | /*********** TIMER OVERFLOW INTERRUPT **********/ 1334 | 1335 | #if defined( __AVR_ATtinyX5__ ) 1336 | ISR(TIMER1_OVF_vect) 1337 | #elif defined( __AVR_ATtinyX4__ ) 1338 | ISR(TIM1_OVF_vect) 1339 | #elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1284P__) 1340 | ISR(TIMER3_OVF_vect) 1341 | #elif defined(__AVR_ATmega328P__) 1342 | ISR(TIMER2_OVF_vect) 1343 | #else 1344 | #error "Manchester library doesnt support your microcontroller" 1345 | #endif 1346 | { 1347 | DEBUG_TOGGLE(); 1348 | MAN_RX_INTERRUPT_HANDLER(); 1349 | } 1350 | 1351 | //end 1352 | --------------------------------------------------------------------------------