DMX512, RDM send/recv library http://mbed.org/users/okini3939/notebook/dmx512

Dependents:   dmx_test ArtNodeLED SPK-DVIMXR SPK-DMXer ... more

DMX512 send/recv library

DMX512 is protocol for lighting.

調光プロトコル DMX512 を送受信するライブラリです。

see: http://mbed.org/users/okini3939/notebook/dmx512/

LPC1114 support is thanks to Stanly Chen

Committer:
okini3939
Date:
Fri Oct 20 00:44:06 2017 +0000
Revision:
19:ae8fd2ba7c53
supported RDM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 19:ae8fd2ba7c53 1 /*
okini3939 19:ae8fd2ba7c53 2 * DMX512, RDM send/recv library
okini3939 19:ae8fd2ba7c53 3 * Copyright (c) 2017 Hiroshi Suga
okini3939 19:ae8fd2ba7c53 4 * Released under the MIT License: http://mbed.org/license/mit
okini3939 19:ae8fd2ba7c53 5 */
okini3939 19:ae8fd2ba7c53 6
okini3939 19:ae8fd2ba7c53 7 /** @file
okini3939 19:ae8fd2ba7c53 8 * @brief DMX512 send/recv
okini3939 19:ae8fd2ba7c53 9 */
okini3939 19:ae8fd2ba7c53 10
okini3939 19:ae8fd2ba7c53 11 #include "mbed.h"
okini3939 19:ae8fd2ba7c53 12 #include "DMX.h"
okini3939 19:ae8fd2ba7c53 13
okini3939 19:ae8fd2ba7c53 14 #ifdef RDM_ENABLE
okini3939 19:ae8fd2ba7c53 15
okini3939 19:ae8fd2ba7c53 16 #define htons(n) __REV16(n)
okini3939 19:ae8fd2ba7c53 17 #define ntohs(n) __REV16(n)
okini3939 19:ae8fd2ba7c53 18 #define htonl(n) __REV(n)
okini3939 19:ae8fd2ba7c53 19 #define ntohl(n) __REV(n)
okini3939 19:ae8fd2ba7c53 20
okini3939 19:ae8fd2ba7c53 21 static unsigned char uid_broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
okini3939 19:ae8fd2ba7c53 22
okini3939 19:ae8fd2ba7c53 23 void DMX::pollRdm () {
okini3939 19:ae8fd2ba7c53 24 int i, len, crc, forMe, forGrp, forAll;
okini3939 19:ae8fd2ba7c53 25 struct RDM_DATA *rdm = (struct RDM_DATA *)data_rx;
okini3939 19:ae8fd2ba7c53 26
okini3939 19:ae8fd2ba7c53 27 if (!is_rdm_received) return;
okini3939 19:ae8fd2ba7c53 28 is_rdm_received = 0;
okini3939 19:ae8fd2ba7c53 29 if (rdm->Length < 24) return;
okini3939 19:ae8fd2ba7c53 30
okini3939 19:ae8fd2ba7c53 31 len = rdm->DataLength;
okini3939 19:ae8fd2ba7c53 32 crc = (rdm->Data[len] << 8) | rdm->Data[len + 1];
okini3939 19:ae8fd2ba7c53 33 if (calcCrc(data_rx, rdm->Length - 1) != crc) return;
okini3939 19:ae8fd2ba7c53 34
okini3939 19:ae8fd2ba7c53 35 forMe = memcmp(rdm_uid, rdm->DestID, 6) == 0 ? 1 : 0;
okini3939 19:ae8fd2ba7c53 36 forGrp = (rdm_uid[0] == rdm->DestID[0] && rdm_uid[1] == rdm->DestID[1] && memcmp(&rdm_uid[2], uid_broadcast, 4) == 0) ? 1 : 0;
okini3939 19:ae8fd2ba7c53 37 forAll = memcmp(rdm_uid, uid_broadcast, 6) == 0 ? 1 : 0;
okini3939 19:ae8fd2ba7c53 38
okini3939 19:ae8fd2ba7c53 39 switch (rdm->CmdClass) {
okini3939 19:ae8fd2ba7c53 40 case E120_DISCOVERY_COMMAND:
okini3939 19:ae8fd2ba7c53 41 switch (ntohs(rdm->Parameter)) {
okini3939 19:ae8fd2ba7c53 42 case E120_DISC_UNIQUE_BRANCH:
okini3939 19:ae8fd2ba7c53 43 if (rdm->DataLength == 12 && !rdm_mute) {
okini3939 19:ae8fd2ba7c53 44 if (memcmp(rdm_uid, &rdm->Data[0], 6) >= 0 && memcmp(rdm_uid, &rdm->Data[6], 6) <= 0) {
okini3939 19:ae8fd2ba7c53 45 sendRdmDiscResponse(rdm);
okini3939 19:ae8fd2ba7c53 46 }
okini3939 19:ae8fd2ba7c53 47 }
okini3939 19:ae8fd2ba7c53 48 break;
okini3939 19:ae8fd2ba7c53 49
okini3939 19:ae8fd2ba7c53 50 case E120_DISC_MUTE:
okini3939 19:ae8fd2ba7c53 51 case E120_DISC_UN_MUTE:
okini3939 19:ae8fd2ba7c53 52 if (forMe || forGrp || forAll) {
okini3939 19:ae8fd2ba7c53 53 if (rdm->CmdClass == E120_DISC_MUTE) {
okini3939 19:ae8fd2ba7c53 54 rdm_mute = 1;
okini3939 19:ae8fd2ba7c53 55 } else {
okini3939 19:ae8fd2ba7c53 56 rdm_mute = 0;
okini3939 19:ae8fd2ba7c53 57 }
okini3939 19:ae8fd2ba7c53 58 if (forMe) sendRdmDiscMuteResponse(rdm);
okini3939 19:ae8fd2ba7c53 59 }
okini3939 19:ae8fd2ba7c53 60 break;
okini3939 19:ae8fd2ba7c53 61
okini3939 19:ae8fd2ba7c53 62 }
okini3939 19:ae8fd2ba7c53 63 break;
okini3939 19:ae8fd2ba7c53 64
okini3939 19:ae8fd2ba7c53 65 case E120_DISCOVERY_COMMAND_RESPONSE:
okini3939 19:ae8fd2ba7c53 66 switch (ntohs(rdm->Parameter)) {
okini3939 19:ae8fd2ba7c53 67 case E120_DISC_MUTE:
okini3939 19:ae8fd2ba7c53 68 case E120_DISC_UN_MUTE:
okini3939 19:ae8fd2ba7c53 69 if (forMe && memcmp(found_uid, rdm->SourceID, 6) == 0) {
okini3939 19:ae8fd2ba7c53 70 if (buf_uid_size && buf_uid_count < buf_uid_size) {
okini3939 19:ae8fd2ba7c53 71 memcpy(&buf_uid[6 * buf_uid_count], rdm->SourceID, 6);
okini3939 19:ae8fd2ba7c53 72 buf_uid_count ++;
okini3939 19:ae8fd2ba7c53 73 }
okini3939 19:ae8fd2ba7c53 74 }
okini3939 19:ae8fd2ba7c53 75 }
okini3939 19:ae8fd2ba7c53 76 break;
okini3939 19:ae8fd2ba7c53 77
okini3939 19:ae8fd2ba7c53 78 case E120_GET_COMMAND:
okini3939 19:ae8fd2ba7c53 79 case E120_SET_COMMAND:
okini3939 19:ae8fd2ba7c53 80 if ((forMe || forGrp || forAll) && cb_RdmParser) {
okini3939 19:ae8fd2ba7c53 81 cb_RdmParser(rdm);
okini3939 19:ae8fd2ba7c53 82 }
okini3939 19:ae8fd2ba7c53 83 break;
okini3939 19:ae8fd2ba7c53 84
okini3939 19:ae8fd2ba7c53 85 case E120_GET_COMMAND_RESPONSE:
okini3939 19:ae8fd2ba7c53 86 case E120_SET_COMMAND_RESPONSE:
okini3939 19:ae8fd2ba7c53 87 if ((forMe || forGrp || forAll) && cb_RdmParser) {
okini3939 19:ae8fd2ba7c53 88 cb_RdmParser(rdm);
okini3939 19:ae8fd2ba7c53 89 }
okini3939 19:ae8fd2ba7c53 90 break;
okini3939 19:ae8fd2ba7c53 91 }
okini3939 19:ae8fd2ba7c53 92 }
okini3939 19:ae8fd2ba7c53 93
okini3939 19:ae8fd2ba7c53 94 int DMX::calcCrc (unsigned char *buf, int len, int offset) {
okini3939 19:ae8fd2ba7c53 95 int i, crc = offset;
okini3939 19:ae8fd2ba7c53 96
okini3939 19:ae8fd2ba7c53 97 for (i = 0; i < len; i ++) {
okini3939 19:ae8fd2ba7c53 98 crc += buf[i];
okini3939 19:ae8fd2ba7c53 99 }
okini3939 19:ae8fd2ba7c53 100 return crc;
okini3939 19:ae8fd2ba7c53 101 }
okini3939 19:ae8fd2ba7c53 102
okini3939 19:ae8fd2ba7c53 103 void DMX::rdmStart (int block) {
okini3939 19:ae8fd2ba7c53 104 Timer t;
okini3939 19:ae8fd2ba7c53 105
okini3939 19:ae8fd2ba7c53 106 t.start();
okini3939 19:ae8fd2ba7c53 107 while (mode_rx != DMX_MODE_BEGIN && t.read_ms() < 100) {
okini3939 19:ae8fd2ba7c53 108 pollRdm();
okini3939 19:ae8fd2ba7c53 109 }
okini3939 19:ae8fd2ba7c53 110 t.stop();
okini3939 19:ae8fd2ba7c53 111
okini3939 19:ae8fd2ba7c53 112 mode_rdm = 1;
okini3939 19:ae8fd2ba7c53 113 mode_rx = DMX_MODE_BEGIN;
okini3939 19:ae8fd2ba7c53 114 mode_tx = DMX_MODE_BEGIN;
okini3939 19:ae8fd2ba7c53 115 is_sent = 0;
okini3939 19:ae8fd2ba7c53 116 is_received = 0;
okini3939 19:ae8fd2ba7c53 117 is_rdm_received = 0;
okini3939 19:ae8fd2ba7c53 118 timeout01.attach_us(this, &DMX::int_timer, RDM_TIME_DELAY);
okini3939 19:ae8fd2ba7c53 119
okini3939 19:ae8fd2ba7c53 120 if (block) {
okini3939 19:ae8fd2ba7c53 121 while (mode_rdm);
okini3939 19:ae8fd2ba7c53 122 }
okini3939 19:ae8fd2ba7c53 123 }
okini3939 19:ae8fd2ba7c53 124
okini3939 19:ae8fd2ba7c53 125 void DMX::rdmWaitResponse (int ms) {
okini3939 19:ae8fd2ba7c53 126 Timer t;
okini3939 19:ae8fd2ba7c53 127
okini3939 19:ae8fd2ba7c53 128 t.start();
okini3939 19:ae8fd2ba7c53 129 while (t.read_ms() < ms && !is_rdm_received) {
okini3939 19:ae8fd2ba7c53 130 pollRdm();
okini3939 19:ae8fd2ba7c53 131 }
okini3939 19:ae8fd2ba7c53 132 t.stop();
okini3939 19:ae8fd2ba7c53 133 pollRdm();
okini3939 19:ae8fd2ba7c53 134 }
okini3939 19:ae8fd2ba7c53 135
okini3939 19:ae8fd2ba7c53 136 int DMX::sendRdmDiscResponse (struct RDM_DATA *rdm) {
okini3939 19:ae8fd2ba7c53 137 int crc;
okini3939 19:ae8fd2ba7c53 138 unsigned char data[40];
okini3939 19:ae8fd2ba7c53 139
okini3939 19:ae8fd2ba7c53 140 data[0] = 0xFE;
okini3939 19:ae8fd2ba7c53 141 data[1] = 0xFE;
okini3939 19:ae8fd2ba7c53 142 data[2] = 0xFE;
okini3939 19:ae8fd2ba7c53 143 data[3] = 0xFE;
okini3939 19:ae8fd2ba7c53 144 data[4] = 0xFE;
okini3939 19:ae8fd2ba7c53 145 data[5] = 0xFE;
okini3939 19:ae8fd2ba7c53 146 data[6] = 0xFE;
okini3939 19:ae8fd2ba7c53 147 data[7] = 0xAA;
okini3939 19:ae8fd2ba7c53 148 data[8] = rdm_uid[0] | 0xAA;
okini3939 19:ae8fd2ba7c53 149 data[9] = rdm_uid[0] | 0x55;
okini3939 19:ae8fd2ba7c53 150 data[10] = rdm_uid[1] | 0xAA;
okini3939 19:ae8fd2ba7c53 151 data[11] = rdm_uid[1] | 0x55;
okini3939 19:ae8fd2ba7c53 152 data[12] = rdm_uid[2] | 0xAA;
okini3939 19:ae8fd2ba7c53 153 data[13] = rdm_uid[2] | 0x55;
okini3939 19:ae8fd2ba7c53 154 data[14] = rdm_uid[3] | 0xAA;
okini3939 19:ae8fd2ba7c53 155 data[15] = rdm_uid[3] | 0x55;
okini3939 19:ae8fd2ba7c53 156 data[16] = rdm_uid[4] | 0xAA;
okini3939 19:ae8fd2ba7c53 157 data[17] = rdm_uid[4] | 0x55;
okini3939 19:ae8fd2ba7c53 158 data[18] = rdm_uid[5] | 0xAA;
okini3939 19:ae8fd2ba7c53 159 data[19] = rdm_uid[5] | 0x55;
okini3939 19:ae8fd2ba7c53 160 crc = calcCrc(&data[8], 12, 0);
okini3939 19:ae8fd2ba7c53 161 data[20] = ((crc >> 8) & 0xFF) | 0xAA;
okini3939 19:ae8fd2ba7c53 162 data[21] = ((crc >> 8) & 0xFF) | 0x55;
okini3939 19:ae8fd2ba7c53 163 data[22] = (crc & 0xFF) | 0xAA;
okini3939 19:ae8fd2ba7c53 164 data[23] = (crc & 0xFF) | 0x55;
okini3939 19:ae8fd2ba7c53 165
okini3939 19:ae8fd2ba7c53 166 wait_us(RDM_TIME_DELAY);
okini3939 19:ae8fd2ba7c53 167 /*
okini3939 19:ae8fd2ba7c53 168 do {
okini3939 19:ae8fd2ba7c53 169 wait_us(RDM_TIME_DELAY * (rand() / (RAND_MAX / 10)));
okini3939 19:ae8fd2ba7c53 170 } while (mode_rx != DMX_MODE_BEGIN);
okini3939 19:ae8fd2ba7c53 171 */
okini3939 19:ae8fd2ba7c53 172 if (_xmit) _xmit->write(XMIT_TX);
okini3939 19:ae8fd2ba7c53 173 wait_us(10);
okini3939 19:ae8fd2ba7c53 174 for (int i = 0; i < 24; i ++) {
okini3939 19:ae8fd2ba7c53 175 _dmx.putc(data[i]);
okini3939 19:ae8fd2ba7c53 176 }
okini3939 19:ae8fd2ba7c53 177 while (!(_uart->LSR & (1<<6))); // TEMT
okini3939 19:ae8fd2ba7c53 178 if (_xmit) _xmit->write(XMIT_RX);
okini3939 19:ae8fd2ba7c53 179
okini3939 19:ae8fd2ba7c53 180 return 0;
okini3939 19:ae8fd2ba7c53 181 }
okini3939 19:ae8fd2ba7c53 182
okini3939 19:ae8fd2ba7c53 183 int DMX::sendRdmMsg (struct RDM_DATA *rdm, int CmdClass, unsigned char *data, int len) {
okini3939 19:ae8fd2ba7c53 184 int crc;
okini3939 19:ae8fd2ba7c53 185 struct RDM_DATA *rdm_msg = (struct RDM_DATA *)data_rdm;
okini3939 19:ae8fd2ba7c53 186
okini3939 19:ae8fd2ba7c53 187 while (mode_rdm);
okini3939 19:ae8fd2ba7c53 188 rdm_msgcount ++;
okini3939 19:ae8fd2ba7c53 189 rdm_msg->SubStartCode = E120_SC_SUB_MESSAGE;
okini3939 19:ae8fd2ba7c53 190 rdm_msg->Length = 24 + len;
okini3939 19:ae8fd2ba7c53 191 memcpy(rdm_msg->DestID, rdm->SourceID, 6);
okini3939 19:ae8fd2ba7c53 192 memcpy(rdm_msg->SourceID, rdm_uid, 6);
okini3939 19:ae8fd2ba7c53 193 rdm_msg->TransactionNo = rdm->TransactionNo;
okini3939 19:ae8fd2ba7c53 194 rdm_msg->ResponseType = E120_RESPONSE_TYPE_ACK;
okini3939 19:ae8fd2ba7c53 195 rdm_msg->MessageCount = rdm_msgcount;
okini3939 19:ae8fd2ba7c53 196 rdm_msg->SubDev = 0;
okini3939 19:ae8fd2ba7c53 197 rdm_msg->CmdClass = CmdClass;
okini3939 19:ae8fd2ba7c53 198 rdm_msg->Parameter = rdm->Parameter;
okini3939 19:ae8fd2ba7c53 199 rdm_msg->DataLength = len;
okini3939 19:ae8fd2ba7c53 200 if (data && len) {
okini3939 19:ae8fd2ba7c53 201 memcpy(rdm_msg->Data, data, len);
okini3939 19:ae8fd2ba7c53 202 }
okini3939 19:ae8fd2ba7c53 203 crc = calcCrc((unsigned char *)rdm_msg, rdm_msg->Length - 1);
okini3939 19:ae8fd2ba7c53 204 rdm_msg->Data[len] = (crc >> 8) & 0xFF;
okini3939 19:ae8fd2ba7c53 205 rdm_msg->Data[len + 1] = crc & 0xFF;
okini3939 19:ae8fd2ba7c53 206
okini3939 19:ae8fd2ba7c53 207 rdmStart();
okini3939 19:ae8fd2ba7c53 208 return 0;
okini3939 19:ae8fd2ba7c53 209 }
okini3939 19:ae8fd2ba7c53 210
okini3939 19:ae8fd2ba7c53 211 int DMX::sendRdmMsg (unsigned char *dest, int CmdClass, int Parameter, int Type, unsigned char *data, int len, int block) {
okini3939 19:ae8fd2ba7c53 212 int crc;
okini3939 19:ae8fd2ba7c53 213 struct RDM_DATA *rdm_msg = (struct RDM_DATA *)data_rdm;
okini3939 19:ae8fd2ba7c53 214
okini3939 19:ae8fd2ba7c53 215 while (mode_rdm);
okini3939 19:ae8fd2ba7c53 216 rdm_transno ++;
okini3939 19:ae8fd2ba7c53 217 rdm_msgcount ++;
okini3939 19:ae8fd2ba7c53 218 rdm_msg->SubStartCode = E120_SC_SUB_MESSAGE;
okini3939 19:ae8fd2ba7c53 219 rdm_msg->Length = 24 + len;
okini3939 19:ae8fd2ba7c53 220 memcpy(rdm_msg->DestID, dest, 6);
okini3939 19:ae8fd2ba7c53 221 memcpy(rdm_msg->SourceID, rdm_uid, 6);
okini3939 19:ae8fd2ba7c53 222 rdm_msg->TransactionNo = rdm_transno;
okini3939 19:ae8fd2ba7c53 223 rdm_msg->ResponseType = Type;
okini3939 19:ae8fd2ba7c53 224 rdm_msg->MessageCount = rdm_msgcount;
okini3939 19:ae8fd2ba7c53 225 rdm_msg->SubDev = 0;
okini3939 19:ae8fd2ba7c53 226 rdm_msg->CmdClass = CmdClass;
okini3939 19:ae8fd2ba7c53 227 rdm_msg->Parameter = htons(Parameter);
okini3939 19:ae8fd2ba7c53 228 rdm_msg->DataLength = len;
okini3939 19:ae8fd2ba7c53 229 if (data && len) {
okini3939 19:ae8fd2ba7c53 230 memcpy(rdm_msg->Data, data, len);
okini3939 19:ae8fd2ba7c53 231 }
okini3939 19:ae8fd2ba7c53 232 crc = calcCrc((unsigned char *)rdm_msg, rdm_msg->Length - 1);
okini3939 19:ae8fd2ba7c53 233 rdm_msg->Data[len] = (crc >> 8) & 0xFF;
okini3939 19:ae8fd2ba7c53 234 rdm_msg->Data[len + 1] = crc & 0xFF;
okini3939 19:ae8fd2ba7c53 235
okini3939 19:ae8fd2ba7c53 236 rdmStart(block);
okini3939 19:ae8fd2ba7c53 237 return 0;
okini3939 19:ae8fd2ba7c53 238 }
okini3939 19:ae8fd2ba7c53 239
okini3939 19:ae8fd2ba7c53 240 int DMX::sendRdmDiscMuteResponse (struct RDM_DATA *rdm) {
okini3939 19:ae8fd2ba7c53 241 unsigned char data[2] = {0, 0};
okini3939 19:ae8fd2ba7c53 242
okini3939 19:ae8fd2ba7c53 243 return sendRdmMsg(rdm, E120_DISCOVERY_COMMAND_RESPONSE, data, 2);
okini3939 19:ae8fd2ba7c53 244 }
okini3939 19:ae8fd2ba7c53 245
okini3939 19:ae8fd2ba7c53 246 void DMX::attachRdmCallback (void (*handler)(struct RDM_DATA *), char *uid) {
okini3939 19:ae8fd2ba7c53 247
okini3939 19:ae8fd2ba7c53 248 cb_RdmParser = handler;
okini3939 19:ae8fd2ba7c53 249 memcpy(rdm_uid, uid, 6);
okini3939 19:ae8fd2ba7c53 250 }
okini3939 19:ae8fd2ba7c53 251
okini3939 19:ae8fd2ba7c53 252 void DMX::int_rdm () {
okini3939 19:ae8fd2ba7c53 253 int flg, dat;
okini3939 19:ae8fd2ba7c53 254
okini3939 19:ae8fd2ba7c53 255 flg = _uart->LSR;
okini3939 19:ae8fd2ba7c53 256 dat = _dmx.getc();
okini3939 19:ae8fd2ba7c53 257
okini3939 19:ae8fd2ba7c53 258 if (flg & ((1 << 7)|(1 << 3)|(1 << 4))) {
okini3939 19:ae8fd2ba7c53 259 // Conflict
okini3939 19:ae8fd2ba7c53 260 addr_rx = -1;
okini3939 19:ae8fd2ba7c53 261 return;
okini3939 19:ae8fd2ba7c53 262 }
okini3939 19:ae8fd2ba7c53 263
okini3939 19:ae8fd2ba7c53 264 if (addr_rx >= 0 && addr_rx < DMX_SIZE) {
okini3939 19:ae8fd2ba7c53 265 data_rx[addr_rx] = dat;
okini3939 19:ae8fd2ba7c53 266 addr_rx ++;
okini3939 19:ae8fd2ba7c53 267 }
okini3939 19:ae8fd2ba7c53 268 }
okini3939 19:ae8fd2ba7c53 269
okini3939 19:ae8fd2ba7c53 270 int DMX::sendRdmDiscMute (unsigned char *dest, int mute) {
okini3939 19:ae8fd2ba7c53 271
okini3939 19:ae8fd2ba7c53 272 while (mode_rdm);
okini3939 19:ae8fd2ba7c53 273
okini3939 19:ae8fd2ba7c53 274 int param = mute ? E120_DISC_MUTE : E120_DISC_UN_MUTE;
okini3939 19:ae8fd2ba7c53 275 sendRdmMsg(dest, E120_DISCOVERY_COMMAND, param ,E120_RESPONSE_TYPE_ACK_TIMER, NULL, 0, 1);
okini3939 19:ae8fd2ba7c53 276 rdmWaitResponse(100);
okini3939 19:ae8fd2ba7c53 277 return 0;
okini3939 19:ae8fd2ba7c53 278 }
okini3939 19:ae8fd2ba7c53 279
okini3939 19:ae8fd2ba7c53 280 int DMX::sendRdmDiscovery (uint64_t uid_begin, uint64_t uid_end) {
okini3939 19:ae8fd2ba7c53 281 int crc;
okini3939 19:ae8fd2ba7c53 282 unsigned char data[12];
okini3939 19:ae8fd2ba7c53 283
okini3939 19:ae8fd2ba7c53 284 while (mode_rdm);
okini3939 19:ae8fd2ba7c53 285
okini3939 19:ae8fd2ba7c53 286 data[ 0] = (uid_begin >> 40) & 0xff;
okini3939 19:ae8fd2ba7c53 287 data[ 1] = (uid_begin >> 32) & 0xff;
okini3939 19:ae8fd2ba7c53 288 data[ 2] = (uid_begin >> 24) & 0xff;
okini3939 19:ae8fd2ba7c53 289 data[ 3] = (uid_begin >> 16) & 0xff;
okini3939 19:ae8fd2ba7c53 290 data[ 4] = (uid_begin >> 8) & 0xff;
okini3939 19:ae8fd2ba7c53 291 data[ 5] = uid_begin & 0xff;
okini3939 19:ae8fd2ba7c53 292 data[ 6] = (uid_end >> 40) & 0xff;
okini3939 19:ae8fd2ba7c53 293 data[ 7] = (uid_end >> 32) & 0xff;
okini3939 19:ae8fd2ba7c53 294 data[ 8] = (uid_end >> 24) & 0xff;
okini3939 19:ae8fd2ba7c53 295 data[ 9] = (uid_end >> 16) & 0xff;
okini3939 19:ae8fd2ba7c53 296 data[10] = (uid_end >> 8) & 0xff;
okini3939 19:ae8fd2ba7c53 297 data[11] = uid_end & 0xff;
okini3939 19:ae8fd2ba7c53 298
okini3939 19:ae8fd2ba7c53 299 _dmx.attach(this, &DMX::int_rdm, Serial::RxIrq);
okini3939 19:ae8fd2ba7c53 300 addr_rx = 0;
okini3939 19:ae8fd2ba7c53 301 sendRdmMsg(uid_broadcast, E120_DISCOVERY_COMMAND, E120_DISC_UNIQUE_BRANCH ,E120_RESPONSE_TYPE_ACK_TIMER, data, 12, 1);
okini3939 19:ae8fd2ba7c53 302 rdmWaitResponse(100);
okini3939 19:ae8fd2ba7c53 303 _dmx.attach(this, &DMX::int_rx, Serial::RxIrq);
okini3939 19:ae8fd2ba7c53 304
okini3939 19:ae8fd2ba7c53 305 if (addr_rx >= 24) {
okini3939 19:ae8fd2ba7c53 306 if (data_rx[0] == 0xfe && data_rx[7] == 0xaa) {
okini3939 19:ae8fd2ba7c53 307 crc = calcCrc(&data_rx[8], 12, 0);
okini3939 19:ae8fd2ba7c53 308 if (data_rx[20] == (((crc >> 8) & 0xFF) | 0xAA) &&
okini3939 19:ae8fd2ba7c53 309 data_rx[21] == (((crc >> 8) & 0xFF) | 0x55) &&
okini3939 19:ae8fd2ba7c53 310 data_rx[22] == ((crc & 0xFF) | 0xAA) && data_rx[23] == ((crc & 0xFF) | 0x55)) {
okini3939 19:ae8fd2ba7c53 311 found_uid[0] = (data_rx[ 8] & 0x55) | (data_rx[ 9] & 0xAA);
okini3939 19:ae8fd2ba7c53 312 found_uid[1] = (data_rx[10] & 0x55) | (data_rx[11] & 0xAA);
okini3939 19:ae8fd2ba7c53 313 found_uid[2] = (data_rx[12] & 0x55) | (data_rx[13] & 0xAA);
okini3939 19:ae8fd2ba7c53 314 found_uid[3] = (data_rx[14] & 0x55) | (data_rx[15] & 0xAA);
okini3939 19:ae8fd2ba7c53 315 found_uid[4] = (data_rx[16] & 0x55) | (data_rx[17] & 0xAA);
okini3939 19:ae8fd2ba7c53 316 found_uid[5] = (data_rx[18] & 0x55) | (data_rx[19] & 0xAA);
okini3939 19:ae8fd2ba7c53 317 return 1;
okini3939 19:ae8fd2ba7c53 318 }
okini3939 19:ae8fd2ba7c53 319 return -1;
okini3939 19:ae8fd2ba7c53 320 }
okini3939 19:ae8fd2ba7c53 321 return -1;
okini3939 19:ae8fd2ba7c53 322 } else
okini3939 19:ae8fd2ba7c53 323 if (addr_rx) {
okini3939 19:ae8fd2ba7c53 324 return -1;
okini3939 19:ae8fd2ba7c53 325 }
okini3939 19:ae8fd2ba7c53 326
okini3939 19:ae8fd2ba7c53 327 return 0;
okini3939 19:ae8fd2ba7c53 328 }
okini3939 19:ae8fd2ba7c53 329
okini3939 19:ae8fd2ba7c53 330 int DMX::rdmDiscoverySub (uint64_t uid_begin, uint64_t uid_end, int ttl) {
okini3939 19:ae8fd2ba7c53 331 int r;
okini3939 19:ae8fd2ba7c53 332 uint64_t uid_mid;
okini3939 19:ae8fd2ba7c53 333
okini3939 19:ae8fd2ba7c53 334 // printf("rdmDiscoverySub %04x %08x - %04x %08x\r\n", (int)(uid_begin>>32), (int)uid_begin, (int)(uid_end>>32), (int)uid_end);
okini3939 19:ae8fd2ba7c53 335 if (!ttl) return 0;
okini3939 19:ae8fd2ba7c53 336 ttl --;
okini3939 19:ae8fd2ba7c53 337
okini3939 19:ae8fd2ba7c53 338 r = sendRdmDiscovery(uid_begin, uid_end);
okini3939 19:ae8fd2ba7c53 339 if (uid_begin >= uid_end) {
okini3939 19:ae8fd2ba7c53 340 if (r > 0) {
okini3939 19:ae8fd2ba7c53 341 sendRdmDiscMute(found_uid, 1);
okini3939 19:ae8fd2ba7c53 342 }
okini3939 19:ae8fd2ba7c53 343 } else {
okini3939 19:ae8fd2ba7c53 344 if (r > 0) {
okini3939 19:ae8fd2ba7c53 345 sendRdmDiscMute(found_uid, 1);
okini3939 19:ae8fd2ba7c53 346 }
okini3939 19:ae8fd2ba7c53 347 if (r) {
okini3939 19:ae8fd2ba7c53 348 uid_mid = (uid_begin + uid_end) / 2;
okini3939 19:ae8fd2ba7c53 349 r = rdmDiscoverySub(uid_begin, uid_mid, ttl);
okini3939 19:ae8fd2ba7c53 350 r |= rdmDiscoverySub(uid_mid + 1, uid_end, ttl);
okini3939 19:ae8fd2ba7c53 351 }
okini3939 19:ae8fd2ba7c53 352 }
okini3939 19:ae8fd2ba7c53 353 return r;
okini3939 19:ae8fd2ba7c53 354 }
okini3939 19:ae8fd2ba7c53 355
okini3939 19:ae8fd2ba7c53 356 int DMX::rdmDiscovery (unsigned char *buf, int size) {
okini3939 19:ae8fd2ba7c53 357
okini3939 19:ae8fd2ba7c53 358 buf_uid_count = 0;
okini3939 19:ae8fd2ba7c53 359 buf_uid_size = size;
okini3939 19:ae8fd2ba7c53 360 buf_uid = buf;
okini3939 19:ae8fd2ba7c53 361 sendRdmDiscMute(uid_broadcast, 0);
okini3939 19:ae8fd2ba7c53 362 rdmDiscoverySub(0x000000000000, 0xfffffffffffe, 10);
okini3939 19:ae8fd2ba7c53 363 return buf_uid_count;
okini3939 19:ae8fd2ba7c53 364 }
okini3939 19:ae8fd2ba7c53 365
okini3939 19:ae8fd2ba7c53 366 #endif