Test program to send MAX!-Messages with a RFM22-Module

Dependencies:   RF22 TextLCD TextLCDScroll mbed RF22Max

Committer:
charly
Date:
Tue Aug 20 20:22:43 2013 +0000
Revision:
2:941c46d37d7e
Parent:
1:b71f9a293c54
Child:
3:4254b4c3557e
Initial version! Reads and decodes a window sensor. No Send, No ACK, No other devices

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charly 2:941c46d37d7e 1 // Testprogramm for RFM22B with RF22-Library to read ELV MAX! window Shutter-Contacts
charly 0:94dd393bd9bb 2
charly 0:94dd393bd9bb 3 #include "mbed.h"
charly 2:941c46d37d7e 4 #include <RF22.h>
charly 0:94dd393bd9bb 5
charly 2:941c46d37d7e 6 #include "TextLCDScroll.h"
charly 2:941c46d37d7e 7
charly 2:941c46d37d7e 8
charly 2:941c46d37d7e 9 #define lengthof(x) (sizeof(x) / sizeof(*x))
charly 0:94dd393bd9bb 10
charly 0:94dd393bd9bb 11 Serial pc(USBTX, USBRX);
charly 0:94dd393bd9bb 12
charly 2:941c46d37d7e 13 //TextLCDScroll lcd(p30, p29, p28, p27, p26, p25, TextLCD::LCD16x2); // rs, e, d4-d7
charly 2:941c46d37d7e 14 TextLCDScroll lcd(p30, p29, p28, p27, p26, p25, TextLCD::LCD16x2); // rs, e, d4-d7
charly 1:b71f9a293c54 15
charly 0:94dd393bd9bb 16 // mbed LEDs
charly 2:941c46d37d7e 17 DigitalOut led1(LED1);
charly 2:941c46d37d7e 18 DigitalOut led2(LED2);
charly 2:941c46d37d7e 19 DigitalOut led3(LED3);
charly 2:941c46d37d7e 20 DigitalOut led4(LED4);
charly 0:94dd393bd9bb 21
charly 0:94dd393bd9bb 22
charly 0:94dd393bd9bb 23 // Singleton instance of the radio
charly 0:94dd393bd9bb 24 //rf22(PinName slaveSelectPin , PinName mosi, PinName miso, PinName sclk, PinName interrupt );
charly 0:94dd393bd9bb 25 RF22 rf22(p14,p11,p12,p13,p15);
charly 0:94dd393bd9bb 26
charly 1:b71f9a293c54 27
charly 2:941c46d37d7e 28 const RF22::ModemConfig config = { // for MAX! protocol
charly 2:941c46d37d7e 29 .reg_1c = 0x01,
charly 2:941c46d37d7e 30 .reg_1f = 0x03,
charly 2:941c46d37d7e 31 .reg_20 = 0x90,
charly 2:941c46d37d7e 32 .reg_21 = 0x20,
charly 2:941c46d37d7e 33 .reg_22 = 0x51,
charly 2:941c46d37d7e 34 .reg_23 = 0xea,
charly 2:941c46d37d7e 35 .reg_24 = 0x00,
charly 2:941c46d37d7e 36 .reg_25 = 0x58,
charly 2:941c46d37d7e 37 /* 2c - 2e are only for OOK */
charly 2:941c46d37d7e 38 .reg_2c = 0x00,
charly 2:941c46d37d7e 39 .reg_2d = 0x00,
charly 2:941c46d37d7e 40 .reg_2e = 0x00,
charly 2:941c46d37d7e 41 .reg_58 = 0x80, /* Copied from RF22 defaults */
charly 2:941c46d37d7e 42 .reg_69 = 0x60, /* Copied from RF22 defaults */
charly 2:941c46d37d7e 43 .reg_6e = 0x08,
charly 2:941c46d37d7e 44 .reg_6f = 0x31,
charly 2:941c46d37d7e 45 .reg_70 = 0x24,
charly 2:941c46d37d7e 46 .reg_71 = RF22_DTMOD_FIFO | RF22_MODTYP_FSK,
charly 2:941c46d37d7e 47 .reg_72 = 0x1e,
charly 2:941c46d37d7e 48 };
charly 2:941c46d37d7e 49
charly 2:941c46d37d7e 50 /* Sync words to send / check for. Don't forget to update RF22_SYNCLEN
charly 2:941c46d37d7e 51 * below if changing the length of this array. */
charly 2:941c46d37d7e 52 const uint8_t sync_words[] = {
charly 2:941c46d37d7e 53 0xc6,
charly 2:941c46d37d7e 54 0x26,
charly 2:941c46d37d7e 55 0xc6,
charly 2:941c46d37d7e 56 0x26,
charly 2:941c46d37d7e 57 };
charly 2:941c46d37d7e 58
charly 2:941c46d37d7e 59 enum modes {MODE_AUTO, MODE_MANUAL, MODE_TEMPORARY, MODE_BOOST};
charly 2:941c46d37d7e 60 const char *mode_str[] = {
charly 2:941c46d37d7e 61 [MODE_AUTO] = "auto",
charly 2:941c46d37d7e 62 [MODE_MANUAL] = "manual",
charly 2:941c46d37d7e 63 [MODE_TEMPORARY] = "temporary",
charly 2:941c46d37d7e 64 [MODE_BOOST] = "boost"
charly 2:941c46d37d7e 65 };
charly 1:b71f9a293c54 66
charly 2:941c46d37d7e 67 char *type_str(uint8_t type)
charly 2:941c46d37d7e 68 {
charly 2:941c46d37d7e 69 switch(type) {
charly 2:941c46d37d7e 70 case 0x00:
charly 2:941c46d37d7e 71 return "PairPing";
charly 2:941c46d37d7e 72 case 0x01:
charly 2:941c46d37d7e 73 return "PairPong";
charly 2:941c46d37d7e 74 case 0x02:
charly 2:941c46d37d7e 75 return "Ack";
charly 2:941c46d37d7e 76 case 0x03:
charly 2:941c46d37d7e 77 return "TimeInformation";
charly 2:941c46d37d7e 78 case 0x10:
charly 2:941c46d37d7e 79 return "ConfigWeekProfile";
charly 2:941c46d37d7e 80 case 0x11:
charly 2:941c46d37d7e 81 return "ConfigTemperatures";
charly 2:941c46d37d7e 82 case 0x12:
charly 2:941c46d37d7e 83 return "ConfigValve";
charly 2:941c46d37d7e 84 case 0x20:
charly 2:941c46d37d7e 85 return "AddLinkPartner";
charly 2:941c46d37d7e 86 case 0x21:
charly 2:941c46d37d7e 87 return "RemoveLinkPartner";
charly 2:941c46d37d7e 88 case 0x22:
charly 2:941c46d37d7e 89 return "SetGroupId";
charly 2:941c46d37d7e 90 case 0x23:
charly 2:941c46d37d7e 91 return "RemoveGroupId";
charly 2:941c46d37d7e 92 case 0x30:
charly 2:941c46d37d7e 93 return "ShutterContactState";
charly 2:941c46d37d7e 94 case 0x40:
charly 2:941c46d37d7e 95 return "SetTemperature";
charly 2:941c46d37d7e 96 case 0x42:
charly 2:941c46d37d7e 97 return "WallThermostatState";
charly 2:941c46d37d7e 98 case 0x43:
charly 2:941c46d37d7e 99 return "SetComfortTemperature";
charly 2:941c46d37d7e 100 case 0x44:
charly 2:941c46d37d7e 101 return "SetEcoTemperature";
charly 2:941c46d37d7e 102 case 0x50:
charly 2:941c46d37d7e 103 return "PushButtonState";
charly 2:941c46d37d7e 104 case 0x60:
charly 2:941c46d37d7e 105 return "ThermostatState";
charly 2:941c46d37d7e 106 case 0x82:
charly 2:941c46d37d7e 107 return "SetDisplayActualTemperature";
charly 2:941c46d37d7e 108 case 0xF1:
charly 2:941c46d37d7e 109 return "WakeUp";
charly 2:941c46d37d7e 110 case 0xF0:
charly 2:941c46d37d7e 111 return "Reset";
charly 2:941c46d37d7e 112 }
charly 2:941c46d37d7e 113 return "Unknown";
charly 1:b71f9a293c54 114 }
charly 1:b71f9a293c54 115
charly 2:941c46d37d7e 116
charly 2:941c46d37d7e 117 /* First 255 bytes of PN9 sequence used for data whitening by the CC1101
charly 2:941c46d37d7e 118 * chip. The RF22 chip is documented to support the same data whitening
charly 2:941c46d37d7e 119 * algorithm, but in practice seems to use a different sequence.
charly 2:941c46d37d7e 120 *
charly 2:941c46d37d7e 121 * Data was generated using the following python snippet:
charly 2:941c46d37d7e 122 *
charly 2:941c46d37d7e 123 import itertools
charly 2:941c46d37d7e 124 def pn9(state):
charly 2:941c46d37d7e 125 while True:
charly 2:941c46d37d7e 126 yield hex(state & 0xff)
charly 2:941c46d37d7e 127 # The pn9 generator is clocked 8 times while shifting in the
charly 2:941c46d37d7e 128 # next data byte
charly 2:941c46d37d7e 129 for i in range(8):
charly 2:941c46d37d7e 130 state = (state >> 1) + (((state & 1) ^ (state >> 5) & 1) << 8)
charly 2:941c46d37d7e 131 print(list(itertools.islice(pn9(0x1ff), 255)))
charly 2:941c46d37d7e 132 */
charly 1:b71f9a293c54 133
charly 2:941c46d37d7e 134 const uint8_t pn9[] = {
charly 2:941c46d37d7e 135 0xff, 0xe1, 0x1d, 0x9a, 0xed, 0x85, 0x33, 0x24,
charly 2:941c46d37d7e 136 0xea, 0x7a, 0xd2, 0x39, 0x70, 0x97, 0x57, 0x0a,
charly 2:941c46d37d7e 137 0x54, 0x7d, 0x2d, 0xd8, 0x6d, 0x0d, 0xba, 0x8f,
charly 2:941c46d37d7e 138 0x67, 0x59, 0xc7, 0xa2, 0xbf, 0x34, 0xca, 0x18,
charly 2:941c46d37d7e 139 0x30, 0x53, 0x93, 0xdf, 0x92, 0xec, 0xa7, 0x15,
charly 2:941c46d37d7e 140 0x8a, 0xdc, 0xf4, 0x86, 0x55, 0x4e, 0x18, 0x21,
charly 2:941c46d37d7e 141 0x40, 0xc4, 0xc4, 0xd5, 0xc6, 0x91, 0x8a, 0xcd,
charly 2:941c46d37d7e 142 0xe7, 0xd1, 0x4e, 0x09, 0x32, 0x17, 0xdf, 0x83,
charly 2:941c46d37d7e 143 0xff, 0xf0, 0x0e, 0xcd, 0xf6, 0xc2, 0x19, 0x12,
charly 2:941c46d37d7e 144 0x75, 0x3d, 0xe9, 0x1c, 0xb8, 0xcb, 0x2b, 0x05,
charly 2:941c46d37d7e 145 0xaa, 0xbe, 0x16, 0xec, 0xb6, 0x06, 0xdd, 0xc7,
charly 2:941c46d37d7e 146 0xb3, 0xac, 0x63, 0xd1, 0x5f, 0x1a, 0x65, 0x0c,
charly 2:941c46d37d7e 147 0x98, 0xa9, 0xc9, 0x6f, 0x49, 0xf6, 0xd3, 0x0a,
charly 2:941c46d37d7e 148 0x45, 0x6e, 0x7a, 0xc3, 0x2a, 0x27, 0x8c, 0x10,
charly 2:941c46d37d7e 149 0x20, 0x62, 0xe2, 0x6a, 0xe3, 0x48, 0xc5, 0xe6,
charly 2:941c46d37d7e 150 0xf3, 0x68, 0xa7, 0x04, 0x99, 0x8b, 0xef, 0xc1,
charly 2:941c46d37d7e 151 0x7f, 0x78, 0x87, 0x66, 0x7b, 0xe1, 0x0c, 0x89,
charly 2:941c46d37d7e 152 0xba, 0x9e, 0x74, 0x0e, 0xdc, 0xe5, 0x95, 0x02,
charly 2:941c46d37d7e 153 0x55, 0x5f, 0x0b, 0x76, 0x5b, 0x83, 0xee, 0xe3,
charly 2:941c46d37d7e 154 0x59, 0xd6, 0xb1, 0xe8, 0x2f, 0x8d, 0x32, 0x06,
charly 2:941c46d37d7e 155 0xcc, 0xd4, 0xe4, 0xb7, 0x24, 0xfb, 0x69, 0x85,
charly 2:941c46d37d7e 156 0x22, 0x37, 0xbd, 0x61, 0x95, 0x13, 0x46, 0x08,
charly 2:941c46d37d7e 157 0x10, 0x31, 0x71, 0xb5, 0x71, 0xa4, 0x62, 0xf3,
charly 2:941c46d37d7e 158 0x79, 0xb4, 0x53, 0x82, 0xcc, 0xc5, 0xf7, 0xe0,
charly 2:941c46d37d7e 159 0x3f, 0xbc, 0x43, 0xb3, 0xbd, 0x70, 0x86, 0x44,
charly 2:941c46d37d7e 160 0x5d, 0x4f, 0x3a, 0x07, 0xee, 0xf2, 0x4a, 0x81,
charly 2:941c46d37d7e 161 0xaa, 0xaf, 0x05, 0xbb, 0xad, 0x41, 0xf7, 0xf1,
charly 2:941c46d37d7e 162 0x2c, 0xeb, 0x58, 0xf4, 0x97, 0x46, 0x19, 0x03,
charly 2:941c46d37d7e 163 0x66, 0x6a, 0xf2, 0x5b, 0x92, 0xfd, 0xb4, 0x42,
charly 2:941c46d37d7e 164 0x91, 0x9b, 0xde, 0xb0, 0xca, 0x09, 0x23, 0x04,
charly 2:941c46d37d7e 165 0x88, 0x98, 0xb8, 0xda, 0x38, 0x52, 0xb1, 0xf9,
charly 2:941c46d37d7e 166 0x3c, 0xda, 0x29, 0x41, 0xe6, 0xe2, 0x7b
charly 2:941c46d37d7e 167 };
charly 0:94dd393bd9bb 168
charly 2:941c46d37d7e 169 /**
charly 2:941c46d37d7e 170 * CRC code based on example from Texas Instruments DN502, matches
charly 2:941c46d37d7e 171 * CC1101 implementation
charly 2:941c46d37d7e 172 */
charly 2:941c46d37d7e 173 #define CRC16_POLY 0x8005
charly 2:941c46d37d7e 174 uint16_t calc_crc_step(uint8_t crcData, uint16_t crcReg)
charly 2:941c46d37d7e 175 {
charly 2:941c46d37d7e 176 uint8_t i;
charly 2:941c46d37d7e 177 for (i = 0; i < 8; i++) {
charly 2:941c46d37d7e 178 if (((crcReg & 0x8000) >> 8) ^ (crcData & 0x80))
charly 2:941c46d37d7e 179 crcReg = (crcReg << 1) ^ CRC16_POLY;
charly 2:941c46d37d7e 180 else
charly 2:941c46d37d7e 181 crcReg = (crcReg << 1);
charly 2:941c46d37d7e 182 crcData <<= 1;
charly 2:941c46d37d7e 183 }
charly 2:941c46d37d7e 184 return crcReg;
charly 2:941c46d37d7e 185 } // culCalcCRC
charly 2:941c46d37d7e 186
charly 2:941c46d37d7e 187 #define CRC_INIT 0xFFFF
charly 2:941c46d37d7e 188 uint16_t calc_crc(uint8_t *buf, size_t len)
charly 2:941c46d37d7e 189 {
charly 2:941c46d37d7e 190 uint16_t checksum;
charly 2:941c46d37d7e 191 checksum = CRC_INIT;
charly 2:941c46d37d7e 192 // Init value for CRC calculation
charly 2:941c46d37d7e 193 for (size_t i = 0; i < len; i++)
charly 2:941c46d37d7e 194 checksum = calc_crc_step(buf[i], checksum);
charly 2:941c46d37d7e 195 return checksum;
charly 0:94dd393bd9bb 196 }
charly 0:94dd393bd9bb 197
charly 2:941c46d37d7e 198 void printHex(uint8_t *buf, size_t len, bool nl)
charly 2:941c46d37d7e 199 {
charly 2:941c46d37d7e 200 for (size_t i = 0; i < len; i++) {
charly 2:941c46d37d7e 201 pc.printf("%02X ",buf[i]);
charly 2:941c46d37d7e 202 }
charly 2:941c46d37d7e 203 if (nl)
charly 2:941c46d37d7e 204 pc.printf("\n\r");
charly 2:941c46d37d7e 205 }
charly 2:941c46d37d7e 206
charly 2:941c46d37d7e 207 void printUntil(uint8_t *buf)
charly 2:941c46d37d7e 208 {
charly 2:941c46d37d7e 209 uint8_t year = buf[1] & 0x3f;
charly 2:941c46d37d7e 210 uint8_t month = ((buf[0] & 0xE0) >> 4) | (buf[1] >> 7);
charly 2:941c46d37d7e 211 uint8_t day = buf[0] & 0x1f;
charly 2:941c46d37d7e 212 /* In 30-minute increments */
charly 2:941c46d37d7e 213 uint8_t time = buf[2] & 0x3f;
charly 0:94dd393bd9bb 214
charly 2:941c46d37d7e 215 pc.printf("Until: 20");
charly 2:941c46d37d7e 216 if (year < 10) pc.printf("0");
charly 2:941c46d37d7e 217 pc.printf("%i",year);
charly 2:941c46d37d7e 218 pc.printf(".");
charly 2:941c46d37d7e 219 if (month < 10) pc.printf("0");
charly 2:941c46d37d7e 220 pc.printf("%i",month);
charly 2:941c46d37d7e 221 pc.printf(".");
charly 2:941c46d37d7e 222 if (day < 10) pc.printf("0");
charly 2:941c46d37d7e 223 pc.printf("%i",day);
charly 2:941c46d37d7e 224 pc.printf(" ");
charly 2:941c46d37d7e 225 if (time < 20) pc.printf("0");
charly 2:941c46d37d7e 226 pc.printf("%i",time / 2);
charly 2:941c46d37d7e 227 if (time % 2)
charly 2:941c46d37d7e 228 pc.printf(":30");
charly 2:941c46d37d7e 229 else
charly 2:941c46d37d7e 230 pc.printf(":00");
charly 2:941c46d37d7e 231 pc.printf("\n\r");
charly 0:94dd393bd9bb 232 }
charly 0:94dd393bd9bb 233
charly 2:941c46d37d7e 234
charly 2:941c46d37d7e 235 void max_rx_loop()
charly 2:941c46d37d7e 236 {
charly 2:941c46d37d7e 237 uint8_t buf[RF22_MAX_MESSAGE_LEN];
charly 2:941c46d37d7e 238 uint8_t len = sizeof(buf);
charly 2:941c46d37d7e 239
charly 2:941c46d37d7e 240 if (rf22.recv(buf, &len)) {
charly 2:941c46d37d7e 241 pc.printf("Recv: ");
charly 2:941c46d37d7e 242 pc.printf("len: %i\n\r",len);
charly 2:941c46d37d7e 243 len = 30; // limit message to 30 Bytes as device receives all 255 Bytes
charly 2:941c46d37d7e 244
charly 2:941c46d37d7e 245 //pc.printf("buf: >%s<\n\r",(char*)buf);
charly 2:941c46d37d7e 246 printHex(buf, len, true);
charly 2:941c46d37d7e 247
charly 2:941c46d37d7e 248 /* Dewhiten data */
charly 2:941c46d37d7e 249 for (int i = 0; i < len; i++)
charly 2:941c46d37d7e 250 buf[i] ^= pn9[i];
charly 2:941c46d37d7e 251
charly 2:941c46d37d7e 252 // now read the real length
charly 2:941c46d37d7e 253 len = buf[0]+3; // 1 length-Byte + 2 CRC
charly 2:941c46d37d7e 254 pc.printf("len: %i\n\r",len);
charly 2:941c46d37d7e 255
charly 2:941c46d37d7e 256 if (len < 3 || len > lengthof(pn9)) {
charly 2:941c46d37d7e 257 pc.printf("Packet length too short/long (%i)\n\r",len);
charly 2:941c46d37d7e 258 return;
charly 2:941c46d37d7e 259 }
charly 2:941c46d37d7e 260 pc.printf("dewhiten: ");
charly 2:941c46d37d7e 261 printHex(buf, len, true);
charly 2:941c46d37d7e 262
charly 2:941c46d37d7e 263 /* Calculate CRC (but don't include the CRC itself) */
charly 2:941c46d37d7e 264 uint16_t crc = calc_crc(buf, len - 2);
charly 2:941c46d37d7e 265 if (buf[len - 1] != (crc & 0xff) || buf[len - 2] != (crc >> 8)) {
charly 2:941c46d37d7e 266 pc.printf("CRC error\n\r");
charly 2:941c46d37d7e 267 return;
charly 2:941c46d37d7e 268 }
charly 2:941c46d37d7e 269
charly 2:941c46d37d7e 270 /* Don't use the CRC as data */
charly 2:941c46d37d7e 271 len -= 2;
charly 2:941c46d37d7e 272
charly 2:941c46d37d7e 273 uint8_t type = buf[3];
charly 2:941c46d37d7e 274 #if 1
charly 2:941c46d37d7e 275 pc.printf("Message count: ");
charly 2:941c46d37d7e 276 printHex(buf + 1, 1, true);
charly 2:941c46d37d7e 277 pc.printf("Flags: ");
charly 2:941c46d37d7e 278 printHex(buf + 2, 1, true);
charly 2:941c46d37d7e 279 pc.printf("Packet type: ");
charly 2:941c46d37d7e 280 printHex(&type, 1, false);
charly 2:941c46d37d7e 281 pc.printf(" (");
charly 2:941c46d37d7e 282 pc.printf(type_str(type));
charly 2:941c46d37d7e 283 pc.printf(")\n\r");
charly 2:941c46d37d7e 284 pc.printf("Packet from: ");
charly 2:941c46d37d7e 285 printHex(buf + 4, 3, true);
charly 2:941c46d37d7e 286 pc.printf("Packet to: ");
charly 2:941c46d37d7e 287 printHex(buf + 7, 3, true);
charly 2:941c46d37d7e 288 pc.printf("GroupID: ");
charly 2:941c46d37d7e 289 printHex(buf + 10, 1, true);
charly 2:941c46d37d7e 290 pc.printf("Payload: ");
charly 2:941c46d37d7e 291 printHex(buf + 11, len-11, true);
charly 0:94dd393bd9bb 292
charly 2:941c46d37d7e 293 if (type == 0x30 && len >= 11) { //ShutterContactState
charly 2:941c46d37d7e 294 bool baterry_low = (buf[11] >> 7) & 0x1;
charly 2:941c46d37d7e 295 bool state = (buf[11]>>1) & 0x1;
charly 2:941c46d37d7e 296 pc.printf("State: ");
charly 2:941c46d37d7e 297 if (state) {
charly 2:941c46d37d7e 298 pc.printf("open\n\r");
charly 2:941c46d37d7e 299 lcd.setLine(1,"open ");
charly 2:941c46d37d7e 300 } else {
charly 2:941c46d37d7e 301 pc.printf("closed\n\r");
charly 2:941c46d37d7e 302 lcd.setLine(1,"closed ");
charly 2:941c46d37d7e 303 }
charly 2:941c46d37d7e 304 pc.printf("Battery: ");
charly 2:941c46d37d7e 305 if (baterry_low) {
charly 2:941c46d37d7e 306 pc.printf("low\n\r");
charly 2:941c46d37d7e 307 } else {
charly 2:941c46d37d7e 308 pc.printf("good\n\r");
charly 2:941c46d37d7e 309 }
charly 2:941c46d37d7e 310
charly 2:941c46d37d7e 311 }
charly 2:941c46d37d7e 312
charly 2:941c46d37d7e 313 /*
charly 2:941c46d37d7e 314 else if (type == 0x60 && len >= 13) { // ThermostatState
charly 2:941c46d37d7e 315 uint8_t mode = buf[11] & 0x3;
charly 2:941c46d37d7e 316 bool dst = (buf[11] >> 2) & 0x1;
charly 2:941c46d37d7e 317 bool locked = (buf[11] >> 5) & 0x1;
charly 2:941c46d37d7e 318 bool baterry_low = (buf[11] >> 7) & 0x1;
charly 2:941c46d37d7e 319 // 0 - 64
charly 2:941c46d37d7e 320 uint8_t valve = buf[12];
charly 2:941c46d37d7e 321 uint8_t set_temp = buf[13];
charly 2:941c46d37d7e 322
charly 2:941c46d37d7e 323 pc.printf("Mode: ");
charly 2:941c46d37d7e 324 pc.printf(mode_str[mode]);
charly 2:941c46d37d7e 325
charly 2:941c46d37d7e 326 pc.printf("Valve pos: %i%",100 * valve / 64);
charly 2:941c46d37d7e 327
charly 2:941c46d37d7e 328 pc.printf("Set temp: %2.1i",set_temp / 2);
charly 0:94dd393bd9bb 329
charly 2:941c46d37d7e 330 if (len > 15 && mode != MODE_TEMPORARY) {
charly 2:941c46d37d7e 331 // In tenths of degrees
charly 2:941c46d37d7e 332 uint8_t actual_temp = ((buf[14] & 0x1) << 8) + buf[15];
charly 2:941c46d37d7e 333 pc.printf("Actual temp: ");
charly 2:941c46d37d7e 334 pc.printf(actual_temp / 10);
charly 2:941c46d37d7e 335 pc.printf(".");
charly 2:941c46d37d7e 336 pc.printf(actual_temp % 10);
charly 2:941c46d37d7e 337 }
charly 2:941c46d37d7e 338 if (len > 16 && mode == MODE_TEMPORARY) {
charly 2:941c46d37d7e 339 printUntil(buf + 14);
charly 2:941c46d37d7e 340 }
charly 2:941c46d37d7e 341 } else if (type == 0x40 && len >= 11) { // SetTemperature
charly 2:941c46d37d7e 342 uint8_t set_temp = buf[11] & 0x3f;
charly 2:941c46d37d7e 343 uint8_t mode = buf[11] >> 6;
charly 2:941c46d37d7e 344
charly 2:941c46d37d7e 345 pc.printf("Mode: ");
charly 2:941c46d37d7e 346 pc.printf(mode_str[mode]);
charly 2:941c46d37d7e 347
charly 2:941c46d37d7e 348 pc.print("Set temp: ");
charly 2:941c46d37d7e 349 pc.printf(set_temp / 2);
charly 2:941c46d37d7e 350 pc.printf(set_temp % 2 ? ".5" : ".0");
charly 2:941c46d37d7e 351 if (len > 14) {
charly 2:941c46d37d7e 352 printUntil(buf + 12);
charly 2:941c46d37d7e 353 }
charly 2:941c46d37d7e 354 }
charly 2:941c46d37d7e 355
charly 2:941c46d37d7e 356 // Print the data
charly 2:941c46d37d7e 357 int i, j;
charly 2:941c46d37d7e 358 for (i = 0; i < len; i += 16) {
charly 2:941c46d37d7e 359 // Hex
charly 2:941c46d37d7e 360 for (j = 0; j < 16 && i+j < len; j++) {
charly 2:941c46d37d7e 361 if (buf[i+j] < 16)
charly 2:941c46d37d7e 362 pc.print("0"); // Sigh, pc.print does not know how to pad hex
charly 2:941c46d37d7e 363 pc.print(buf[i+j], HEX);
charly 2:941c46d37d7e 364 pc.print(" ");
charly 2:941c46d37d7e 365 }
charly 2:941c46d37d7e 366 // Padding on last block
charly 2:941c46d37d7e 367 while (j++ < 16)
charly 2:941c46d37d7e 368 pc.print(" ");
charly 2:941c46d37d7e 369
charly 2:941c46d37d7e 370 pc.print(" ");
charly 2:941c46d37d7e 371 // ASCII
charly 2:941c46d37d7e 372 for (j = 0; j < 16 && i+j < len; j++)
charly 2:941c46d37d7e 373 pc.write(isprint(buf[i+j]) ? buf[i+j] : '.');
charly 2:941c46d37d7e 374 pc.println("");
charly 2:941c46d37d7e 375 }
charly 2:941c46d37d7e 376 */
charly 2:941c46d37d7e 377 pc.printf("\n\r");
charly 2:941c46d37d7e 378 #endif
charly 0:94dd393bd9bb 379 }
charly 0:94dd393bd9bb 380 }
charly 0:94dd393bd9bb 381
charly 2:941c46d37d7e 382 int main()
charly 2:941c46d37d7e 383 {
charly 1:b71f9a293c54 384
charly 0:94dd393bd9bb 385 pc.baud(115200);
charly 0:94dd393bd9bb 386
charly 0:94dd393bd9bb 387 pc.printf("\n\rConnected to mbed\n\r");
charly 0:94dd393bd9bb 388
charly 0:94dd393bd9bb 389
charly 2:941c46d37d7e 390 char version_str [80] = "RF22-MAX!-V1.1";
charly 2:941c46d37d7e 391 lcd.cls();
charly 2:941c46d37d7e 392 lcd.setLine(0,version_str);
charly 2:941c46d37d7e 393 pc.printf("%s\n\r",version_str);
charly 1:b71f9a293c54 394
charly 2:941c46d37d7e 395 pc.printf("Pre-init|");
charly 2:941c46d37d7e 396 if (!rf22.init())
charly 2:941c46d37d7e 397 pc.printf("RF22 init failed\n\r");
charly 2:941c46d37d7e 398 pc.printf("Post-init\n\r");
charly 1:b71f9a293c54 399
charly 1:b71f9a293c54 400
charly 2:941c46d37d7e 401 // try to detect Window-Shutter
charly 1:b71f9a293c54 402
charly 2:941c46d37d7e 403 rf22.setModemRegisters(&config);
charly 2:941c46d37d7e 404 rf22.setFrequency(868.3, 0.035);
charly 2:941c46d37d7e 405 /* Disable TX packet control, since the RF22 doesn't do proper
charly 2:941c46d37d7e 406 * whitening so can't read the length header or CRC. We need RX packet
charly 2:941c46d37d7e 407 * control so the RF22 actually sends pkvalid interrupts when the
charly 2:941c46d37d7e 408 * manually set packet length is reached. */
charly 2:941c46d37d7e 409 rf22.spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_MSBFRST | RF22_ENPACRX);
charly 2:941c46d37d7e 410 /* No packet headers, 4 sync words, fixed packet length */
charly 2:941c46d37d7e 411 rf22.spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_NONE | RF22_HDCH_NONE);
charly 2:941c46d37d7e 412 rf22.spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_0 | RF22_FIXPKLEN | RF22_SYNCLEN_4);
charly 2:941c46d37d7e 413 rf22.setSyncWords(sync_words, lengthof(sync_words));
charly 2:941c46d37d7e 414 /* Detect preamble after 4 nibbles */
charly 2:941c46d37d7e 415 rf22.spiWrite(RF22_REG_35_PREAMBLE_DETECTION_CONTROL1, (0x4 << 3));
charly 2:941c46d37d7e 416 /* Send 8 bytes of preamble */
charly 2:941c46d37d7e 417 rf22.setPreambleLength(8); // in nibbles
charly 2:941c46d37d7e 418 rf22.spiWrite(RF22_REG_3E_PACKET_LENGTH, 20);
charly 1:b71f9a293c54 419
charly 1:b71f9a293c54 420
charly 2:941c46d37d7e 421 rf22.setModeRx();
charly 1:b71f9a293c54 422
charly 1:b71f9a293c54 423
charly 1:b71f9a293c54 424
charly 2:941c46d37d7e 425 //wait forever and see if interrrupt occurs(led1)
charly 2:941c46d37d7e 426 while (1) {
charly 1:b71f9a293c54 427
charly 2:941c46d37d7e 428 max_rx_loop();
charly 2:941c46d37d7e 429 };
charly 0:94dd393bd9bb 430 }
charly 0:94dd393bd9bb 431
charly 0:94dd393bd9bb 432