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
RDM.cpp@19:ae8fd2ba7c53, 2017-10-20 (annotated)
- Committer:
- okini3939
- Date:
- Fri Oct 20 00:44:06 2017 +0000
- Revision:
- 19:ae8fd2ba7c53
supported RDM
Who changed what in which revision?
User | Revision | Line number | New 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 |