DMX interface (DMX in/out, Art-Net in/out, DMX patch) http://mbed.org/users/okini3939/notebook/dmx-platform/
Dependencies: ChaNFSSD EthernetNetIf mbed ConfigFile ChaNFS DmxArtNet
main.cpp@0:41b699bbda83, 2012-03-01 (annotated)
- Committer:
- okini3939
- Date:
- Thu Mar 01 01:40:07 2012 +0000
- Revision:
- 0:41b699bbda83
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okini3939 | 0:41b699bbda83 | 1 | /* |
okini3939 | 0:41b699bbda83 | 2 | * DMX Station - mbed DMX Platform |
okini3939 | 0:41b699bbda83 | 3 | * Copyright (c) 2012 Hiroshi Suga |
okini3939 | 0:41b699bbda83 | 4 | * Released under the MIT License: http://mbed.org/license/mit |
okini3939 | 0:41b699bbda83 | 5 | */ |
okini3939 | 0:41b699bbda83 | 6 | |
okini3939 | 0:41b699bbda83 | 7 | /** @file |
okini3939 | 0:41b699bbda83 | 8 | * @brief DMX Station |
okini3939 | 0:41b699bbda83 | 9 | */ |
okini3939 | 0:41b699bbda83 | 10 | |
okini3939 | 0:41b699bbda83 | 11 | /* |
okini3939 | 0:41b699bbda83 | 12 | * "Node" Device |
okini3939 | 0:41b699bbda83 | 13 | * "Universe" 512 DMX datas |
okini3939 | 0:41b699bbda83 | 14 | * "Sub-Net" 16 Universe |
okini3939 | 0:41b699bbda83 | 15 | * "Server" Controller |
okini3939 | 0:41b699bbda83 | 16 | * |
okini3939 | 0:41b699bbda83 | 17 | * can use over 40 Sub-Net on network. |
okini3939 | 0:41b699bbda83 | 18 | */ |
okini3939 | 0:41b699bbda83 | 19 | |
okini3939 | 0:41b699bbda83 | 20 | #include "dbg.h" |
okini3939 | 0:41b699bbda83 | 21 | #include "mbed.h" |
okini3939 | 0:41b699bbda83 | 22 | #include "EthernetNetIf.h" |
okini3939 | 0:41b699bbda83 | 23 | #include "DmxArtNet.h" |
okini3939 | 0:41b699bbda83 | 24 | #include "DMX.h" |
okini3939 | 0:41b699bbda83 | 25 | #include "NEC950MHz.h" |
okini3939 | 0:41b699bbda83 | 26 | #include "dmx_patch.h" |
okini3939 | 0:41b699bbda83 | 27 | |
okini3939 | 0:41b699bbda83 | 28 | #define LED_NET_ACT_ON led_yk = 0 |
okini3939 | 0:41b699bbda83 | 29 | #define LED_NET_ACT_OFF led_yk = 1 |
okini3939 | 0:41b699bbda83 | 30 | #define LED_NET_G_ON led_gayk = 1; led_gkya = 0 |
okini3939 | 0:41b699bbda83 | 31 | #define LED_NET_Y_ON led_gayk = 0; led_gkya = 1 |
okini3939 | 0:41b699bbda83 | 32 | #define LED_NET_GY_OFF led_gayk = 0; led_gkya = 0 |
okini3939 | 0:41b699bbda83 | 33 | |
okini3939 | 0:41b699bbda83 | 34 | // for Touchable Fountains (Juco) |
okini3939 | 0:41b699bbda83 | 35 | #define UDP_PORT 10465 |
okini3939 | 0:41b699bbda83 | 36 | #define RF_CH 31 |
okini3939 | 0:41b699bbda83 | 37 | |
okini3939 | 0:41b699bbda83 | 38 | DigitalOut led_red(p22), led_yellow(p23); |
okini3939 | 0:41b699bbda83 | 39 | DigitalOut led_gayk(p24),led_gkya(p25), led_yk(p26); |
okini3939 | 0:41b699bbda83 | 40 | DigitalIn eth_link(P1_25), eth_speed(P1_26); |
okini3939 | 0:41b699bbda83 | 41 | DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); |
okini3939 | 0:41b699bbda83 | 42 | EthernetNetIf *eth; |
okini3939 | 0:41b699bbda83 | 43 | Serial pc(USBTX, USBRX); |
okini3939 | 0:41b699bbda83 | 44 | |
okini3939 | 0:41b699bbda83 | 45 | DmxArtNet art; |
okini3939 | 0:41b699bbda83 | 46 | DMX dmx1(p13, p14); |
okini3939 | 0:41b699bbda83 | 47 | DMX dmx2(p28, p27); |
okini3939 | 0:41b699bbda83 | 48 | |
okini3939 | 0:41b699bbda83 | 49 | UDPSocket udp; |
okini3939 | 0:41b699bbda83 | 50 | |
okini3939 | 0:41b699bbda83 | 51 | volatile int patch_update = 0; |
okini3939 | 0:41b699bbda83 | 52 | volatile int art_update[2] = {0, 0}; |
okini3939 | 0:41b699bbda83 | 53 | volatile int rf_update = 0, rf_flg = 0; |
okini3939 | 0:41b699bbda83 | 54 | char dmx_art[2][512] __attribute__((section("AHBSRAM0"))); |
okini3939 | 0:41b699bbda83 | 55 | char dmx_udp[512] __attribute__((section("AHBSRAM0"))); |
okini3939 | 0:41b699bbda83 | 56 | char dmx_rf[512] __attribute__((section("AHBSRAM0"))); |
okini3939 | 0:41b699bbda83 | 57 | |
okini3939 | 0:41b699bbda83 | 58 | |
okini3939 | 0:41b699bbda83 | 59 | extern "C" void mbed_mac_address(char *s); |
okini3939 | 0:41b699bbda83 | 60 | |
okini3939 | 0:41b699bbda83 | 61 | void no_memory () { |
okini3939 | 0:41b699bbda83 | 62 | led_red = 1; |
okini3939 | 0:41b699bbda83 | 63 | printf("panic: can't allocate to memory!\r\n"); |
okini3939 | 0:41b699bbda83 | 64 | exit(-1); |
okini3939 | 0:41b699bbda83 | 65 | } |
okini3939 | 0:41b699bbda83 | 66 | |
okini3939 | 0:41b699bbda83 | 67 | void shutdown () { |
okini3939 | 0:41b699bbda83 | 68 | art.ArtPollReply.NumPorts = 0; |
okini3939 | 0:41b699bbda83 | 69 | strcpy(art.ArtPollReply.NodeReport, "Shutdown"); |
okini3939 | 0:41b699bbda83 | 70 | art.SendArtPollReply(); |
okini3939 | 0:41b699bbda83 | 71 | art.Done(); |
okini3939 | 0:41b699bbda83 | 72 | } |
okini3939 | 0:41b699bbda83 | 73 | |
okini3939 | 0:41b699bbda83 | 74 | void isr_udp (UDPSocketEvent e) { |
okini3939 | 0:41b699bbda83 | 75 | int len; |
okini3939 | 0:41b699bbda83 | 76 | Host remote; |
okini3939 | 0:41b699bbda83 | 77 | |
okini3939 | 0:41b699bbda83 | 78 | if (e == UDPSOCKET_READABLE) { |
okini3939 | 0:41b699bbda83 | 79 | // UDP2DMX |
okini3939 | 0:41b699bbda83 | 80 | LED_NET_ACT_ON; |
okini3939 | 0:41b699bbda83 | 81 | led_yellow = 1; |
okini3939 | 0:41b699bbda83 | 82 | led3 = 1; |
okini3939 | 0:41b699bbda83 | 83 | len = udp.recvfrom((char*)dmx_udp, sizeof(dmx_udp), &remote); |
okini3939 | 0:41b699bbda83 | 84 | DBG("recv udp %d\r\n", len); |
okini3939 | 0:41b699bbda83 | 85 | patch_update = 5; |
okini3939 | 0:41b699bbda83 | 86 | } |
okini3939 | 0:41b699bbda83 | 87 | } |
okini3939 | 0:41b699bbda83 | 88 | |
okini3939 | 0:41b699bbda83 | 89 | void isr_timer () { |
okini3939 | 0:41b699bbda83 | 90 | led_yellow = 0; |
okini3939 | 0:41b699bbda83 | 91 | LED_NET_ACT_OFF; |
okini3939 | 0:41b699bbda83 | 92 | led1 = 0; led2 = 0; led3 = 0; led4 = 0; |
okini3939 | 0:41b699bbda83 | 93 | } |
okini3939 | 0:41b699bbda83 | 94 | |
okini3939 | 0:41b699bbda83 | 95 | int init_artnet (IpAddr *ip) { |
okini3939 | 0:41b699bbda83 | 96 | char mac[6]; |
okini3939 | 0:41b699bbda83 | 97 | EthernetErr ethErr; |
okini3939 | 0:41b699bbda83 | 98 | |
okini3939 | 0:41b699bbda83 | 99 | eth_link.mode(PullUp); |
okini3939 | 0:41b699bbda83 | 100 | eth_speed.mode(PullUp); |
okini3939 | 0:41b699bbda83 | 101 | |
okini3939 | 0:41b699bbda83 | 102 | if (! eth_link) { |
okini3939 | 0:41b699bbda83 | 103 | LED_NET_G_ON; |
okini3939 | 0:41b699bbda83 | 104 | } |
okini3939 | 0:41b699bbda83 | 105 | LED_NET_ACT_ON; |
okini3939 | 0:41b699bbda83 | 106 | |
okini3939 | 0:41b699bbda83 | 107 | // create ip address from mac address |
okini3939 | 0:41b699bbda83 | 108 | mbed_mac_address(mac); |
okini3939 | 0:41b699bbda83 | 109 | *ip = IpAddr(2, mac[3], mac[4], mac[5]); |
okini3939 | 0:41b699bbda83 | 110 | eth = new EthernetNetIf(*ip, IpAddr(255,0,0,0), IpAddr(0,0,0,0), IpAddr(0,0,0,0)); |
okini3939 | 0:41b699bbda83 | 111 | ethErr = eth->setup(); |
okini3939 | 0:41b699bbda83 | 112 | if (ethErr) { |
okini3939 | 0:41b699bbda83 | 113 | LED_NET_Y_ON; |
okini3939 | 0:41b699bbda83 | 114 | led_red = 1; |
okini3939 | 0:41b699bbda83 | 115 | return -1; |
okini3939 | 0:41b699bbda83 | 116 | } |
okini3939 | 0:41b699bbda83 | 117 | |
okini3939 | 0:41b699bbda83 | 118 | wait(2); |
okini3939 | 0:41b699bbda83 | 119 | |
okini3939 | 0:41b699bbda83 | 120 | // init ArtNet |
okini3939 | 0:41b699bbda83 | 121 | art.BindIpAddress = *ip; |
okini3939 | 0:41b699bbda83 | 122 | art.BCastAddress = IpAddr(2,255,255,255); |
okini3939 | 0:41b699bbda83 | 123 | |
okini3939 | 0:41b699bbda83 | 124 | art.InitArtPollReplyDefaults(); |
okini3939 | 0:41b699bbda83 | 125 | // Device |
okini3939 | 0:41b699bbda83 | 126 | art.ArtPollReply.PortType[0] = 128; // output |
okini3939 | 0:41b699bbda83 | 127 | art.ArtPollReply.PortType[1] = 128; // output |
okini3939 | 0:41b699bbda83 | 128 | art.ArtPollReply.PortType[2] = 64; // input |
okini3939 | 0:41b699bbda83 | 129 | art.ArtPollReply.GoodInput[2] = 4; |
okini3939 | 0:41b699bbda83 | 130 | art.ArtPollReply.PortType[3] = 64; // input |
okini3939 | 0:41b699bbda83 | 131 | art.ArtPollReply.GoodInput[3] = 4; |
okini3939 | 0:41b699bbda83 | 132 | |
okini3939 | 0:41b699bbda83 | 133 | art.Init(); |
okini3939 | 0:41b699bbda83 | 134 | art.SendArtPollReply(); // announce to art-net nodes |
okini3939 | 0:41b699bbda83 | 135 | |
okini3939 | 0:41b699bbda83 | 136 | pc.printf("init ArtNet\r\n"); |
okini3939 | 0:41b699bbda83 | 137 | return 0; |
okini3939 | 0:41b699bbda83 | 138 | } |
okini3939 | 0:41b699bbda83 | 139 | |
okini3939 | 0:41b699bbda83 | 140 | int main () { |
okini3939 | 0:41b699bbda83 | 141 | int i; |
okini3939 | 0:41b699bbda83 | 142 | Ticker timer; |
okini3939 | 0:41b699bbda83 | 143 | ifMessage ifmsg; |
okini3939 | 0:41b699bbda83 | 144 | IpAddr ip; |
okini3939 | 0:41b699bbda83 | 145 | UDPSocketErr udpErr; |
okini3939 | 0:41b699bbda83 | 146 | |
okini3939 | 0:41b699bbda83 | 147 | set_new_handler(no_memory); // new handler function |
okini3939 | 0:41b699bbda83 | 148 | |
okini3939 | 0:41b699bbda83 | 149 | pc.baud(112500); |
okini3939 | 0:41b699bbda83 | 150 | |
okini3939 | 0:41b699bbda83 | 151 | memset(dmx_art, 0, sizeof(dmx_art)); |
okini3939 | 0:41b699bbda83 | 152 | memset(dmx_udp, 0, sizeof(dmx_udp)); |
okini3939 | 0:41b699bbda83 | 153 | memset(dmx_rf, 0, sizeof(dmx_rf)); |
okini3939 | 0:41b699bbda83 | 154 | |
okini3939 | 0:41b699bbda83 | 155 | load_patch(); |
okini3939 | 0:41b699bbda83 | 156 | timer.attach(&isr_timer, 0.1); |
okini3939 | 0:41b699bbda83 | 157 | |
okini3939 | 0:41b699bbda83 | 158 | // init ArtNet |
okini3939 | 0:41b699bbda83 | 159 | if (init_artnet(&ip)) return -1; |
okini3939 | 0:41b699bbda83 | 160 | pc.printf("Bind to interface: %d.%d.%d.%d\r\n", (unsigned char)ip[0], (unsigned char)ip[1], (unsigned char)ip[2], (unsigned char)ip[3]); |
okini3939 | 0:41b699bbda83 | 161 | |
okini3939 | 0:41b699bbda83 | 162 | // init UDP2DMX |
okini3939 | 0:41b699bbda83 | 163 | udpErr = udp.bind(Host(ip, UDP_PORT, NULL)); |
okini3939 | 0:41b699bbda83 | 164 | if (udpErr) { |
okini3939 | 0:41b699bbda83 | 165 | pc.printf("Bind error (udp2dmx)\r\n"); |
okini3939 | 0:41b699bbda83 | 166 | return -1; |
okini3939 | 0:41b699bbda83 | 167 | } |
okini3939 | 0:41b699bbda83 | 168 | udp.setOnEvent(&isr_udp); |
okini3939 | 0:41b699bbda83 | 169 | pc.printf("init UDP2DMX\r\n"); |
okini3939 | 0:41b699bbda83 | 170 | |
okini3939 | 0:41b699bbda83 | 171 | // init NEC950MHz |
okini3939 | 0:41b699bbda83 | 172 | if (! init_rf(RF_CH)) { |
okini3939 | 0:41b699bbda83 | 173 | pc.printf("init RF\r\n"); |
okini3939 | 0:41b699bbda83 | 174 | } |
okini3939 | 0:41b699bbda83 | 175 | |
okini3939 | 0:41b699bbda83 | 176 | pc.printf("ArtNode begin\r\n"); |
okini3939 | 0:41b699bbda83 | 177 | |
okini3939 | 0:41b699bbda83 | 178 | for (;;) { |
okini3939 | 0:41b699bbda83 | 179 | Net::poll(); |
okini3939 | 0:41b699bbda83 | 180 | |
okini3939 | 0:41b699bbda83 | 181 | if (! eth_link) { |
okini3939 | 0:41b699bbda83 | 182 | LED_NET_G_ON; |
okini3939 | 0:41b699bbda83 | 183 | } else { |
okini3939 | 0:41b699bbda83 | 184 | LED_NET_GY_OFF; |
okini3939 | 0:41b699bbda83 | 185 | } |
okini3939 | 0:41b699bbda83 | 186 | |
okini3939 | 0:41b699bbda83 | 187 | if (dmx1.is_recived) { |
okini3939 | 0:41b699bbda83 | 188 | // dmx in 1 |
okini3939 | 0:41b699bbda83 | 189 | LED_NET_ACT_ON; |
okini3939 | 0:41b699bbda83 | 190 | led_yellow = 1; |
okini3939 | 0:41b699bbda83 | 191 | led1 = 1; |
okini3939 | 0:41b699bbda83 | 192 | patch_update = 1; |
okini3939 | 0:41b699bbda83 | 193 | dmx1.is_recived = 1; |
okini3939 | 0:41b699bbda83 | 194 | DBG("recv, dmx 1\r\n"); |
okini3939 | 0:41b699bbda83 | 195 | } |
okini3939 | 0:41b699bbda83 | 196 | |
okini3939 | 0:41b699bbda83 | 197 | if (dmx2.is_recived) { |
okini3939 | 0:41b699bbda83 | 198 | // dmx in 2 |
okini3939 | 0:41b699bbda83 | 199 | LED_NET_ACT_ON; |
okini3939 | 0:41b699bbda83 | 200 | led_yellow = 1; |
okini3939 | 0:41b699bbda83 | 201 | led1 = 1; |
okini3939 | 0:41b699bbda83 | 202 | patch_update = 2; |
okini3939 | 0:41b699bbda83 | 203 | dmx2.is_recived = 2; |
okini3939 | 0:41b699bbda83 | 204 | DBG("recv, dmx 2\r\n"); |
okini3939 | 0:41b699bbda83 | 205 | } |
okini3939 | 0:41b699bbda83 | 206 | |
okini3939 | 0:41b699bbda83 | 207 | if (art.Work()) { |
okini3939 | 0:41b699bbda83 | 208 | // ArtNet |
okini3939 | 0:41b699bbda83 | 209 | LED_NET_ACT_ON; |
okini3939 | 0:41b699bbda83 | 210 | led_yellow = 1; |
okini3939 | 0:41b699bbda83 | 211 | led2 = 1; |
okini3939 | 0:41b699bbda83 | 212 | patch_update = art.LastRecievedUniverse + 3; |
okini3939 | 0:41b699bbda83 | 213 | DBG("recv, node %d\r\n", art.LastRecievedUniverse + 1); |
okini3939 | 0:41b699bbda83 | 214 | } |
okini3939 | 0:41b699bbda83 | 215 | |
okini3939 | 0:41b699bbda83 | 216 | if (patch_update) { |
okini3939 | 0:41b699bbda83 | 217 | // update DMX patch |
okini3939 | 0:41b699bbda83 | 218 | led4 = 1; |
okini3939 | 0:41b699bbda83 | 219 | patch(); |
okini3939 | 0:41b699bbda83 | 220 | DBG("update"); |
okini3939 | 0:41b699bbda83 | 221 | |
okini3939 | 0:41b699bbda83 | 222 | for (i = 0; i < 2; i ++) { |
okini3939 | 0:41b699bbda83 | 223 | // ArtNet good status |
okini3939 | 0:41b699bbda83 | 224 | if (art_update[i]) { |
okini3939 | 0:41b699bbda83 | 225 | DBG("art good"); |
okini3939 | 0:41b699bbda83 | 226 | Net::poll(); |
okini3939 | 0:41b699bbda83 | 227 | art.ArtPollReply.GoodInput[i] = 128; |
okini3939 | 0:41b699bbda83 | 228 | art.Send_ArtDmx(i, 0, dmx_art[i], 512); |
okini3939 | 0:41b699bbda83 | 229 | art_update[i] = 0; |
okini3939 | 0:41b699bbda83 | 230 | } |
okini3939 | 0:41b699bbda83 | 231 | } |
okini3939 | 0:41b699bbda83 | 232 | |
okini3939 | 0:41b699bbda83 | 233 | if (! rf_flg && rf_update) { |
okini3939 | 0:41b699bbda83 | 234 | // RF send |
okini3939 | 0:41b699bbda83 | 235 | send_rf(MSGID_SEND_NOACK, 0xffffffff, dmx_rf, 200); |
okini3939 | 0:41b699bbda83 | 236 | rf_flg = 1; |
okini3939 | 0:41b699bbda83 | 237 | rf_update = 0; |
okini3939 | 0:41b699bbda83 | 238 | } |
okini3939 | 0:41b699bbda83 | 239 | |
okini3939 | 0:41b699bbda83 | 240 | patch_update = 0; |
okini3939 | 0:41b699bbda83 | 241 | } |
okini3939 | 0:41b699bbda83 | 242 | |
okini3939 | 0:41b699bbda83 | 243 | if (rf_flg && read_rf(&ifmsg) > 0) { |
okini3939 | 0:41b699bbda83 | 244 | // RF responce |
okini3939 | 0:41b699bbda83 | 245 | DBG("recv %d\r\n", ifmsg.msgid); |
okini3939 | 0:41b699bbda83 | 246 | if (ifmsg.msgid != MSGID_ACK) { |
okini3939 | 0:41b699bbda83 | 247 | DBG("no ack\r\n"); |
okini3939 | 0:41b699bbda83 | 248 | } |
okini3939 | 0:41b699bbda83 | 249 | rf_flg = 0; |
okini3939 | 0:41b699bbda83 | 250 | } |
okini3939 | 0:41b699bbda83 | 251 | } |
okini3939 | 0:41b699bbda83 | 252 | } |
okini3939 | 0:41b699bbda83 | 253 |